Missing Opportunities for Polymorphism
Polymorphism(多态)是面向对象中重要的思想之一。源于希腊语,即多(poly)面(morph)的意思。在程序的上下文中,多态是特定类的对象或方法的多种形态。但多态并不是简单的交替式实现。使用时要小心,多态会创建个很小的局部执行上下文,以让我们无需去关心那冗长的if-then-else代码块。在上下文内部允许我们直接处理事务,但在上下文外部却要强制我们重建它之后才能处理事务。谨慎使用交替实现,我们可以捕获上下文以让代码更少更可读。最好先看个代码示例,比如下面这段简单(到爆)的购物车:
1 | public class ShoppingCart { |
假设我们的网店里陈列着可下载的(虚拟)产品和需要运输的(实物)产品。我们就要让对象支持这些操作:
1 | public class Shipping { |
当用户下单后,我们需要发货:
1 | while (!cart.isEmpty()) { |
代码中的的???
可不是什么花式操作;而是用来询问我该用电子邮件还是快递发送这些商品。但回答这个问题的上下文并不存在,我们只能用布尔
或枚举
的形式事先捕获发货方式,然后用if-then-else去补全这个参数。
另一种解决方案是创建两个继承于Item
的类,称为DownloadableItem
和SurfaceItem
。现在来实现代码,我会让Item
作为一个接口,并支持单一方法——ship
。为了能顺利发货购物车的商品,我们需要调用item.ship(shipper)
。而DownloadableItem
和SurfaceItem
两个类都需要实现ship
:
1 | public class DownloadableItem implements Item { |
在这个例子中,我们将负责运输的工作委托给了每个商品。由于每个商品都清楚自己的最佳发货方式,这种模式可以继续下去,且不在需要if-then-else。这个段代码也示范了两种经常一起使用的设计模式:命令模式和双重调度。能否有效地运用这些设计模式取决于你是否谨慎地使用多态。这样一来,能够大幅缩减代码中的if-then-else。
尽管在某些情况下用if-then-else会比多态更实用,但更多时候,多态的编码风格将产出更小巧、更可读、也更健壮的代码库。错失机会的次数可能就是我们代码中if-then-else的数量。