每天一个设计模式(6):抽象工厂模式
6.抽象工厂模式
抽象工厂模式是对象的创建模式,它是工厂方法模式的进一步推广。通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题。
抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
一.UML关系图二.实现代码
1 //定义不同的产品之间的一定具备的标准,用interface实现 2 //其中的method()方法可看作提取出不同产品的共性,如手机都有类似的功能 3 interface IProductA{ 4 public void method(); 5 } 6 7 interface IProductB{ 8 public void method(); 9 } 10 11 //实现了产品标准实现的一系列具体产品 12 //由于已经设计好A1由厂商1生产,故以下输出代码有“厂商x” 13 class ProductA1 implements IProductA{ 14 public void method() { 15 System.out.println("厂商1 生产ProductA1 ..."); 16 } 17 } 18 19 class ProductA2 implements IProductA{ 20 public void method() { 21 System.out.println("厂商2 生产ProductA2 ..."); 22 } 23 } 24 25 class ProductB1 implements IProductB{ 26 public void method() { 27 System.out.println("厂商1 生产ProductB1 ..."); 28 } 29 } 30 31 class ProductB2 implements IProductB{ 32 public void method() { 33 System.out.println("厂商2 生产ProductB2 ..."); 34 } 35 } 36 37 //每一种牌子的产品生产工厂,即不同的厂商负责自己牌子产品的生产 38 abstract class Factory1{ 39 abstract IProductA getProductA1(); 40 abstract IProductB getProductB1(); 41 } 42 43 abstract class Factory2{ 44 abstract IProductA getProductA2(); 45 abstract IProductB getProductB2(); 46 } 47 48 //具体的工厂用来生产相关的产品 49 class ConcreteFactory1 extends Factory1{ 50 public IProductA getProductA1() { 51 return new ProductA1(); 52 } 53 public IProductB getProductB1() { 54 return new ProductB1(); 55 } 56 } 57 58 class ConcreteFactoryB extends Factory2{ 59 public IProductA getProductA2() { 60 return new ProductA2(); 61 } 62 public IProductB getProductB2() { 63 return new ProductB2(); 64 } 65 } 66 67 //测试类 68 public class Client { 69 public static void main(String[] args) { 70 //厂商1负责生产产品A1、B1 71 Factory1 factory1 = new ConcreteFactory1(); 72 IProductA productA1 = factory1.getProductA1(); 73 IProductB productB1 = factory1.getProductB1(); 74 75 productA1.method(); 76 productB1.method(); 77 78 //厂商2负责生产产品A2、B2 79 Factory2 factory2 = new ConcreteFactoryB(); 80 IProductA productA2 = factory2.getProductA2(); 81 IProductB productB2 = factory2.getProductB2(); 82 83 productA2.method(); 84 productB2.method(); 85 } 86 }
三.抽象工厂模式的优缺点
优点
● 分离接口和实现
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
● 使切换产品族变得容易
因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。
缺点
● 不太容易扩展新的产品
如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
四.应用场景
(1) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
(2) 这个系统有多于一个的产品族,而系统只消费其中某一产品族。
(3) 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
(4) 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
五.工厂方法模式和抽象工厂模式的比较
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。
工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。
抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。即提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。
参考:《Head First设计模式》
http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html
http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html