二、工厂方式模式
简单工厂模式的不足
简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,加入必要的处理逻辑,这违背了“开闭原则”。
在简单工厂模式中,所有的产品都是由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,
严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。
1.模式动机与定义
模式动机
如果需要增加一种新类型的按钮,如椭圆形按钮,那么除了增加一个新的具体产品类之外,
还需要修改工厂类的代码,这就使得整个设计在一定程度上违反了“开闭原则”。
而是将具体按钮的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮、矩形按钮、菱形按钮等,它们实现在抽象按钮工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”
模式定义
1.工厂方法模式(Factory Method Pattern)简称工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。
2.在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,
这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
2.模式结构与分析
模式结构
工厂方法模式包含如下角色:
Product:抽象产品:定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类或接口。
ConcreteProduct:具体产品:实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,他们之间一一对应。
Factory:抽象工厂:声明了工厂方法,用于返回一个产品。与应用程序无关。任何在模式中创建对象的工厂类都必须实现该接口。
ConcreteFactory:具体工厂:具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例。
在具体工厂类中包含与应用程序密切相关的逻辑,并且接受应用程序调用以创建产品对象。
模式分析
1.工厂方法模式是简单工厂模式的进一步抽象和推广
2.工厂方法模式保持了简单工厂模式的优点,并克服了它的缺点
3.核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给其子类去完成
4.可以允许系统在不修改工厂角色的情况下引进新产品
5.增加具体产品-->增加具体工厂,符合“开闭原则”
//抽象工厂类
public abstract class PayMethodFactory{public abstract AbstractPay getPayMethod();
}//具体工厂类
public class CashPayFactory extends PayMethodFactory{public AbstractPay getPayMethod(){return new CashPay();}
}//客户类代码片段
PayMethodFactory factory;
AbstractPay payMethod;
factory=new CashPayFactory();
payMethod =factory.getPayMethod();
payMethod.pay();
//为了提高系统的可扩展性和灵活性,在定义工厂和产品时都必须使用抽象层,
//如果需要更换产品类,只需要更换对应的工厂即可,其他代码不需要进行任何修改。
配置文件的应用
3.模式效果与应用
工厂方法模式优点
1.工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节
2.能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部
3.在系统中加入新产品时,完全符合开闭原则
工厂方法模式缺点
1.系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销
2.增加了系统的抽象性和理解难度
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,
且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
使用工厂方法模式的情况
1.客户端不知道它所需要的对象的类(客户端不需要知道具体产品类的类名只需要知道所对应的工厂即可,具体产品对象由具体工厂类创建)
2.抽象工厂类通过其子类来指定创建哪个对象