Step 59: Missing Opportunities for Polymorphism~ Kirk Pepperdine
This is the 59th Step towards gaining the Programming Enlightenment series. If you didn’t learn the 58th Step, read it.
Polymorphism is the use of a single symbol to represent different types.
Polymorphism is taken from Greek, meaning poly(many) and morph(forms). It is one of the fundamental principal in Object Oriented Programming.
It describes the ability of a particular class of objects to have multiple forms with the help of a single interface for differing underlying forms (data types).
Let’s see the following example;
We have a ShoppingCart that has a number of Item which can be either downloaded or needs to be physically shipped.
public class ShoppingCart {
private ArrayList<Item> cart = new ArrayList<Item>();
public void add(Item item) { cart.add(item); }
public Item takeNext() { return cart.remove(0); }
public boolean isEmpty() { return cart.isEmpty(); }
}
We can define another object that helps in Shipping.
public class Shipping {
public boolean ship(Item item, SurfaceAddress address) { ... }
public boolean ship(Item item, EMailAddress address { ... }
}
In this case, if the client wants to complete the checkout and ship the items, we would have the following code.
while (!cart.isEmpty()) {
shipping.ship(cart.takeNext(), ???);
}
The parameter described here ???, isn’t some fancy elvis operator, rather it’s the shipping method ie by EmailAddress or SurfaceAddress. Since, the ShoppingCart doesn’t have any context, we would require if-then-else condition for checking the type of item before we can ship.
If we had implemented proper Polymorphism, this problem would have been solved without the requiring if-then-else. Let’s define an interface Item which will be implemented by two classes DownloadableItem and SurfaceItem.
public class DownloadableItem implements Item {
public boolean ship(Shipping shipper) {
shipper.ship(this, customer.getEmailAddress());
}
}
public class SurfaceItem implements Item {
public boolean ship(Shipping shipper) {
shipper.ship(this, customer.getSurfaceAddress());
}
}
Here, we have delegated the responsibility of Shipping to each item. Since, now the item knows how it can be shipped, we no longer require if-then-else.
Here, we have used Command and Double Dispatch pattern to achieve polymorphism.
while (!cart.isEmpty()) {
cart.takeNext().ship(shipping);
}
TL;DR The number of missed opportunities in using polymorphism can be stated by the simple count of if-then-else statements in the code..
Go to 58th Step
Go to the 60th Step.
References:
- 97 things Every Programmer Should Know ~ Git Book
- 97 Things Every Programmer Should Know ~ Paperback
- What is polymorphism? ~ Wiki
- What is a polymorphism, what is it for and how is it used? ~ Stackoverflow