抽象工厂
常规的对象创建方法:Road road = new Road();
new 的问题: 实现依赖,不能应对“具体实例化类型”的变化。比如Road要换成waterRoad,这时用到new Road()的地方都要改。
解决思路:封装变化点--哪里变化,封装哪里。如果没有变化,当然不需要额外的封装。
最简单的解决方法:
{
public static Road CreateRoad()
{
return new Road(); //面对新的需求变化,可以写成 return new WaterRoad();
}
}
在客户程序里不用改程序
Road road = roadFactory.CreateRoad();
根据以上思路,我们来创建"一系列相互依赖"的对象:
假设一个游戏开发场景:我们要构造“道路”、“房屋”等。会得出以下代码:
以上可称为简单工厂模式(工厂类里多用静态方法返回对象,所以又称静态工厂模式)。
解决的问题:如果要实例一个waterRoad对象,只要改变roadFactory.CreateRoad()的方法,客户程序不用修改。
存在的问题:当我们需要不同风格的道路、房屋,就不能对原来的类做修改,而要对应建立class aRoadFactory,class bRoadFactory等不同风格的类。这时客户程序的roadFactory.CreateRoad()中的roadFactory类还是要改成aRoadFactory和bRoadFactory,如果对象很多(不只路和房屋,假设还有树、河、风、雨等等),对应要改变的地方就很多。即:简单工厂不能应对“不同系列对象”的变化。
注:如果是一个系列,即只有一种RoadFactory风格,静态工厂就足够了。也再次说明了:如果没有变化,就不需要额外的封装。
如何解决:使用面向对象的技术来“封装”变化点
客户程序(需求改变时此类不需要改变而实现不同的风格):(非Class App)
Abstractor factory模式的几个要点:
A。如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以。
备注:比如游戏的场景(包括道路、房屋、地道)。如果变化的不是对象(很长的时间内场景中的对象都只有道路、房屋、地道),而是风格(即一段时间要推出一种新的场景,由不同风格的道路、房屋、地道组成),这时才适用Abstract Factory模式。如果是反过来,对象不断要增加,如树木,河流等,但场景相对稳定时,就不适用抽象工厂(比如增加一个对象就会引起一系列类的修改)。即分清是对象需要变还是系列需要变。
B。“系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
C。Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
D。Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。