工厂模式
工厂的作用
工厂用来实例化对象,使用工厂是隐藏变化的一种自然结果。
先考虑需要什么对象,然后关注如何创建对象,即先确定对象后定义工厂。
几个与工厂有关的模式
- 单例模式;
- 工厂方法模式;
- 原型模式;
- 抽象工厂模式;
- 建造者模式;
它们都归为创建型模式。
管理和使用原则
两种视角:使用视角、创建/管理视角
两个实体之间的关系只能有下面一种,或者为A使用B,或者为A管理B。这样降低耦合度。
分清了对象的定义工作和管理工作后,我们说能事半功倍
工厂模式分为3类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
简单工厂模式中,产品是抽象的,工厂不是抽象的,在工厂类中面对各种具体产品。这个工厂类不符合开闭原则。工厂类中提供不同方法生成不同的具体产品。调用者面对的是一个工厂类和它们的各个方法。
工厂方法模式定义一个用于创建对象的成员方法,让子类在这个方法中决定创建哪个对象。
工厂方法模式中,产品是抽象的,工厂也是抽象的,每个具体工厂类面对一个具体产品。调用者要面对各个具体工厂类和它们的统一方法。
工厂方***使得工厂对象的数量增长。可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。
工厂方法模式要创建的东西本身是抽象定义的,并且工厂类本身也可能是抽象的。
工厂方法模式将“使用哪些对象”的规则与“如何使用这些对象”的逻辑分离开来。
有时虽然有几组对象,但并不需要每个组都用不同的派生类控制其实例化,可以更加动态一些:使用配置文件指定使用哪些对象,用switch实例化正确的对象。
反射技术
菜鸟程序员碰到问题,只会用时间来摆平。所以即使整天加班,老板也不想给加工资。
所有在用简单工厂的地方,都可以考虑用反射技术+配置文件来去除switch或if,解除分支判断带来的耦合。
Abstract Factory模式为创建一组相关的对象提供一个接口,无需指定具体类。注意这里是创建一组对象,即接口中可能提供每种对象的创建方法。
抽象工厂模式与工厂方法模式的区别
工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广。
工厂方法模式用来创建一个产品的等级结构,而抽象工厂模式用来创建多个产品的等级结构。工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
switch语句说明:
这里可能需要抽象:
需要多态行为;
存在职责错放;
工厂模式并不能消除switch,它将使用switch的职责从调用者中转移了。
switch语句本身没有问题,只有在switch语句互相耦合,比如许多switch语句使用同一个变量作为开关时,这种连接点变成一种依赖性,带来复杂和bug。
示例:
在java中,iterator()方法是工厂方法。
在c++中,begin(),end()都是工厂方法。
一个工厂方法的细节扩展:模板工厂方法
在模板模式中,抽象类中的一个模板方法是用来创建抽象对象的,创建何种具体类推迟到子类中实现。 这个模板工厂方法一般是保护的。
另一个细节延伸模式:建造者模式
建造者模式是围绕构建过程展开的模式。
用于创建一些复杂的对象,这些对象内部构建间的建造过程顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
建造者继承建造接口类,必须实现所有技能;指挥者指挥建造者按顺序施展一些技能。
建造者模式可以把创建复杂对象的算法从该对象的组成部分中独立出来。
可以觉察到,模板工厂方法和建造者模式也是相似的。
再一个建造者模式:Prototype 原型模式
它就是Clone已有对象,基类中提供Clone(),Copy()方法,Clone()方法实现浅复制,Copy()方法实现深复制。