设计模式(4)----抽象工厂模式
-
介绍:
- 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
-
定义:
- 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
-
抽象工厂方法的UML图:
-
组成:
- 抽象工厂:虚拟的造车厂,所有的造车厂的一个概念,是一个规范,也就是代码中的接口
- 具体工厂:具体的造车厂,用来造什么样子车的车厂,也就是是程序中的实现类
- 抽象产品:车的概念,所有车的抽象化,也就是代码中对车的一个接口
- 具体产品:具体的车,什么牌子,什么类型,什么配件,清清楚楚的,也就是抽象产品的一个实现类
-
步骤:
- 创建抽象工厂类:定义工厂的公共接口
package com.lvsling.abstractfactory;
/** * 抽象工厂角色,声明了工厂方法 * @author Administrator * */ public interface Factory { public Engine produceEngine();
public Aircondition produceAircondition(); } |
-
创建抽象产品类:定义产品的公共接口
package com.lvsling.abstractfactory;
/** * 抽象产品角色 * @author Administrator * */ public abstract class Aircondition {
} |
package com.lvsling.abstractfactory;
/** * 抽象产品角色 * @author Administrator * */ public abstract class Engine {
} |
-
创建具体工厂类:定义创建具体产品实例的方法
package com.lvsling.abstractfactory;
/** * 具体工厂类:实现了产品族产品生产的逻辑 * @author Administrator * */ public class FactoryCarA implements Factory {
public FactoryCarA() { System.out.println("具体工厂CarA正在生产:"); }
@Override public Engine produceEngine() { return new Engine_1(); }
@Override public Aircondition produceAircondition() { return new Aircondition_1(); }
} |
package com.lvsling.abstractfactory;
/** * 具体工厂类:实现了产品族产品生产的逻辑 * @author Administrator * */ public class FactoryCarB implements Factory {
public FactoryCarB() { System.out.println("具体工厂CarB正在生产:"); }
@Override public Engine produceEngine() { return new Engine_2(); }
@Override public Aircondition produceAircondition() { return new Aircondition_2(); }
} |
-
创建具体产品类:定义生产具体的产品
package com.lvsling.abstractfactory;
/** * 具体产品角色 * @author Administrator * */ public class Aircondition_1 extends Aircondition { public Aircondition_1() { System.out.println("生产了1空调!"); } } |
package com.lvsling.abstractfactory;
/** * 具体产品角色 * @author Administrator * */ public class Aircondition_2 extends Aircondition{ public Aircondition_2() { System.out.println("生产了2空调"); } } |
package com.lvsling.abstractfactory;
/** * 具体产品角色 * @author Administrator * */ public class Engine_1 extends Engine{ public Engine_1() { System.out.println("生产了1引擎!"); } } |
package com.lvsling.abstractfactory;
/** * 具体产品角色 * @author Administrator * */ public class Engine_2 extends Engine{ public Engine_2() { System.out.println("生产了2引擎!"); } } |
-
创建client类:来调用创建不同目标的方法创建不同具体产品类的实例
package com.lvsling.abstractfactory;
public class Client { public static void main(String[] args) { Factory factoryA = new FactoryCarA(); //生产A型汽车的配件工厂 Engine engineA = factoryA.produceEngine(); Aircondition airconditionA = factoryA.produceAircondition();
Factory factoryB = new FactoryCarB(); Engine engineB = factoryB.produceEngine(); Aircondition airconditionB = factoryB.produceAircondition(); } } |
-
客户端打印:
具体工厂CarA正在生产: 生产了1引擎! 生产了1空调! 具体工厂CarB正在生产: 生产了2引擎! 生产了2空调 |
-
优点:
- 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
-
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
-
增加新的具体工厂和产品族很方便,无须修改已有系统,符合"开闭原则"。
-
缺点:
- 增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对"开闭原则"的支持呈现倾斜性。
-
应用场景:
- 当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。
- 一个继承体系中,如果存在着多个等级结构,并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式
-
总结:
- 其实,对于简单工厂模式,工厂方法模式,抽象工厂模式不必要过于吹毛求疵,这些模式都属于工厂模式,形式和特点上都有很多相似之处,他们的最终目的都是为了解耦合。提高代码的灵活性和可重用性。在使用时,不必刻意去要求它是工厂方法模式还是抽象工厂模式,需求不同,做相应的更改,明明使用的工厂方法模式,你加了个新方法,在类中的产品中构成了不同等级结构中的产品族,就变成抽象工厂方法了。等价言之,你使用抽象工厂模式,需求不同,你减少了一个方法提供的产品不在构成等级结构的产品族,自然而然就是工厂方法模式了。主要在乎的还是代码的耦合度是否符合我们的目的。