为了满足“开闭原则”,大部分设计模式都引入了抽象层,如工厂方法模式、抽象工厂模式、适配器模式、桥接模式、命令模式、策略模式等等。客户端代码针对抽象层编程,而在程序运行的时候再指定其子类,根据“里氏代换原则”和面向对象的多态性,子类对象在运行时将覆盖父类对象。如果需要对系统进行扩展或修改,只需修改子类类名即可。在具体实现时,通过引入配置文件可以使得用户在不修改任何客户端代码的前提下增加或替换子类,其基本实现过程如下:
(1)客户端针对抽象层编程,客户端代码中不能出现任何具体类类名,即客户端不直接实例化对象;
(2)引入纯文本格式的配置文件,通常是XML文件,将具体类类名存储在配置文件中;
(3)通过DOM(Document Object Model,文档对象模型)、SAX(Simple APIfor XML)等XML解析技术获取存储在配置文件中的类名;
(4)在客户端代码中通过反射(Reflection)机制根据类名创建对象,用反射所创建的对象替换父类对象的引用,程序运行时,将调用子类方法来实现业务功能;
(5)如果需要扩展功能,只需增加一个新的子类继承抽象父类,再修改配置文件,重新运行程序即可;如果需要替换功能,只需用另一个子类类名替换存储在配置文件中的原有子类类名即可。无论是扩展还是替换都无须修改既有类库和客户端源代码,完全符合开闭原则。
下面通过工厂方法模式来说明如何使用配置文件和反射机制:
【实例说明】:宝马(BMW)工厂可以生产宝马轿车,奔驰(Benz)工厂可以生产奔驰轿车,使用工厂方法模式来设计该场景,所得类图如图1所示:
图1 工厂方法模式实例类图
在图1中,CarFactory是抽象工厂,声明了工厂方法produceCar(),在其子类中实现了该方法,用于返回具体的产品。在客户端代码中将出现如下代码: