抽象工厂模式,Abstract Factory,按GOF的划分属于对象创建型模式,用于提供一个创建一系列相关或相互依赖对象的接口,而不用指定它们具体实现的类,很好的实践了“面向接口编程”的准则。
一、使用场景:
1、一个系统要独立于它的产品的创建,组合和表示,比如跨操作系统的文本编辑器,文本编辑器操作的应该是编辑器视图组件独立于操作系统的抽象,而不是具体于某操作系统的实现。
2、一个系统要由多个产品系列中的一个来配置时,比如常见的系统主题,系统可以有多套主题,客户可以根据自己的喜欢选择一套来使用。
3、当你要强调一系列相关的产品对象的设计以便进行联合使用时,这有助于提供一致的接口和实现。
4、当你要提供一个产品类库,而只想显示它们的接口而不是实现时。产品类库重在可以复用,如果与具体的实现过渡耦合,自然降低了产品类库的价值。
二、UML图:
三、java实现
/** * 抽象工厂接口,用于生产一系列相关产品 * @author qbg */ public interface IFactory { /** * 生产产品A */ IProductA createProductA(); /** * 生产产品B */ IProductB createProProductB(); }
/** * 产品A的抽象接口,用于抽象A产品的公共操作 * @author qbg * */ public interface IProductA { public void method1(); public void method2(); }
/** * 产品族B的抽象接口,用于抽象产品B的公共操作 * @author qbg * */ public interface IProductB { public void method1(); public void method2(); }
/** * 抽象工厂接口的一种具体实现,用于产生1系列的A,B产品 * @author qbg * */ public class ConcreteFactory1 implements IFactory { @Override public IProductA createProductA() { return new ProductA1(); } @Override public IProductB createProProductB() { return new ProductB1(); } }
/** * 抽象工厂接口的另一种具体实现,用于产生2系列的A,B产品 * @author qbg * */ public class ConcreteFactory2 implements IFactory { @Override public IProductA createProductA() { return new ProductA2(); } @Override public IProductB createProProductB() { return new ProductB2(); } }
/** * 产品A系列的一种具体实现:ProductA1 * @author qbg * */ public class ProductA1 implements IProductA { @Override public void method1() { System.out.println("productA1-method1"); } @Override public void method2() { System.out.println("productA1-method2"); } }
/** * 产品B系列的一种具体实现:ProductB1 * @author qbg * */ public class ProductB1 implements IProductB { @Override public void method1() { System.out.println("productB1-method1"); } @Override public void method2() { System.out.println("productB1-method2"); } }
/** * 产品A系列的另一种具体实现:ProductA2 * @author qbg * */ public class ProductA2 implements IProductA{ @Override public void method1() { System.out.println("productA2-method1"); } @Override public void method2() { System.out.println("productA2-method2"); } }
/** * 产品B系列的另一种具体实现:ProductB2 * @author qbg * */ public class ProductB2 implements IProductB{ @Override public void method1() { System.out.println("productB2-method1"); } @Override public void method2() { System.out.println("productB2-method2"); } }
/** * 客户端代码,抽象工厂和抽象产品接口的使用者 * @author qbg * */ public class Client { private IFactory factory; private IProductA productA; private IProductB productB; public Client(IFactory factory){ this.factory = factory; } public void product(){ productA = factory.createProductA(); productB = factory.createProProductB(); } public void consumeProductA(){ productA.method1(); productA.method2(); } public void consumeProductB(){ productB.method1(); productB.method2(); } public static void main(String[] args) { //生产消费1系列A,B产品 Client c1 = new Client(new ConcreteFactory1()); c1.product(); c1.consumeProductA(); c1.consumeProductB(); //生产消费2系列A,B产品 Client c2 = new Client(new ConcreteFactory2()); c2.product(); c2.consumeProductA(); c2.consumeProductB(); } }
运行结果:
生产消费1系列A,B产品 productA1-method1 productA1-method2 productB1-method1 productB1-method2 生产消费2系列A,B产品 productA2-method1 productA2-method2 productB2-method1 productB2-method2
四、模式优缺点
优点:
1、分离具体实现,面向接口编程。客户端代码只需访问抽象接口而不需关心具体的实现类,解耦。
2、易于交换产品系列。由于抽象工厂为产品系列提供了统一的抽象层,所以如果想交换产品系列,只需交换相应的具体实现。
3、有利于产品的一致性,这得力于抽象工厂提供的一致抽象。
缺点:
1、难以支持新种类的产品。如果在现有产品系列中添加新的产品,那就要修改现有产品系列的抽象工厂接口,这样必然引起各产品系列抽象工厂的具体实现需要改变。