工厂三姐妹分别是简单工厂模式、工厂方法模式、抽象工厂模式。
1. 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
2. 优点:是包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
3. 缺点: 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求。这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了,违反了“开——闭原则”。
结构图如下:
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。解决了许多简单工厂模式的问题,首先完全实现‘开放-封闭 原则’,实现了可扩展。其次,更复杂的层次结构,可以应用于产品结果复杂的场合。
工厂方法模式用来生产同一等级结构中的固定产品(支持增加和扩展)步骤如下:
1、 一个工厂创建一个产品,所有的具体工厂继承自一个抽象工厂。
2 、客户端先创建不同产品工厂,再由工厂创建具体产品,
3、 产品的创建逻辑分散在每个具体工厂中。客户端只依赖于抽象工厂与抽象产品,不依赖于具体的工厂与具体产品增。增加新产品是需要增加工厂类和产品类,符合OCP原则。
简而言之,工厂方法把简单工厂的内部的逻辑判断移到了客户端进行,要想增加功能,简单工厂模式是该工厂类,工厂方法是该客户端。
结构图如下:
解析上图:
抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂(ConcreteCreator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。
具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
抽象工厂模式(Abstract Factory):提供一个创建型一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式是工厂模式家族中最为抽象和最具一般性的一种形态。
结构图如下:
优点:第一个优点是易于交互产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。第二个优点是它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
缺点:如果增加一个功能,至少要增加一个抽象产品AbstractProductC和两个具体产品ProductC1、ProductC2,还得更改抽象工厂接口AbstractFactory和具体的工厂ConcreteFactory1、ConcreteFactory2.
举《大话设计模式》书中的例子说明:进行加减乘除运算。他们都会提炼出一个抽象类:运算类,和四个具体的运算类:加法类、减法类、乘法类、除法类。简单工厂模式还有一个简单工厂类,在这个简单工厂类中就会有判断是加法、减法、乘法还是除法。而工厂方法模式有一个抽象工厂类和四个具体的:加法工厂、减法工厂、乘法工厂、除法工厂。
结构图分别如下所示:
1、简单工厂模式:
2、工厂方法模式:
3、抽象工厂模式他不止增加一个产品类,也就是除了一个产品运算类,还有其他的产品类。
(图略)
按照顺序,是抽象程度依次加深。简单工厂模式最易理解。当需要一个相同的接口,但里面完成内容不同的时候,就可以用一个工厂来产生其中多个类的一个实例。它最明显的是有一个工厂类来产生接口实例。
工厂方法模式是简单工厂的抽象加深,它不需要一个独立来创建对象。而是通过子类延迟创建需要的对象。如在汽车的对象里面包括了发动机对象,但发动机对象不是由特定的工厂类来产生,而是取决于到底是什么样的汽车,不同的汽车有不同的发动机对象,这就是交给了子类来完成。
而抽象工厂则有点类似简单工厂模式 + 工厂方法模式。 它的好处是通过抽象类来隔离具体类,并通过唯一入口来决定产生什么具体类。我们使用它的前提条件是一系列相似的类。