设计模式初探-抽象工厂模式

来源:互联网 发布:linux查看运行的服务 编辑:程序博客网 时间:2024/06/06 14:15

抽象工厂模式,Abstract Factory,按GOF的划分属于对象创建型模式,用于提供一个创建一系列相关或相互依赖对象的接口,而不用指定它们具体实现的类,很好的实践了“面向接口编程”的准则。

一、使用场景:

1、一个系统要独立于它的产品的创建,组合和表示,比如跨操作系统的文本编辑器,文本编辑器操作的应该是编辑器视图组件独立于操作系统的抽象,而不是具体于某操作系统的实现。

2、一个系统要由多个产品系列中的一个来配置时,比如常见的系统主题,系统可以有多套主题,客户可以根据自己的喜欢选择一套来使用。

3、当你要强调一系列相关的产品对象的设计以便进行联合使用时,这有助于提供一致的接口和实现。

4、当你要提供一个产品类库,而只想显示它们的接口而不是实现时。产品类库重在可以复用,如果与具体的实现过渡耦合,自然降低了产品类库的价值。

二、UML图:

抽象工厂uml图

三、Java实现

[java] view plain copy
  1. /** 
  2.  * 抽象工厂接口,用于生产一系列相关产品 
  3.  * @author qbg 
  4.  */  
  5. public interface IFactory {  
  6.     /** 
  7.      * 生产产品A 
  8.      */  
  9.     IProductA createProductA();  
  10.     /** 
  11.      * 生产产品B 
  12.      */  
  13.     IProductB createProProductB();  
  14. }  
[java] view plain copy
  1. /** 
  2.  * 产品A的抽象接口,用于抽象A产品的公共操作 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public interface IProductA {  
  7.     public void method1();  
  8.     public void method2();  
  9. }  
[java] view plain copy
  1. /** 
  2.  * 产品族B的抽象接口,用于抽象产品B的公共操作 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public interface IProductB {  
  7.  public void method1();  
  8.  public void method2();  
  9. }  
[java] view plain copy
  1. /** 
  2.  * 抽象工厂接口的一种具体实现,用于产生1系列的A,B产品 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ConcreteFactory1 implements IFactory {  
  7.   
  8.     @Override  
  9.     public IProductA createProductA() {  
  10.         return new ProductA1();  
  11.     }  
  12.   
  13.     @Override  
  14.     public IProductB createProProductB() {  
  15.         return new ProductB1();  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 抽象工厂接口的另一种具体实现,用于产生2系列的A,B产品 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ConcreteFactory2 implements IFactory {  
  7.   
  8.     @Override  
  9.     public IProductA createProductA() {  
  10.         return new ProductA2();  
  11.     }  
  12.   
  13.     @Override  
  14.     public IProductB createProProductB() {  
  15.         return new ProductB2();  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 产品A系列的一种具体实现:ProductA1 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ProductA1 implements IProductA {  
  7.   
  8.     @Override  
  9.     public void method1() {  
  10.         System.out.println("productA1-method1");  
  11.     }  
  12.   
  13.     @Override  
  14.     public void method2() {  
  15.         System.out.println("productA1-method2");  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 产品B系列的一种具体实现:ProductB1 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ProductB1 implements IProductB {  
  7.   
  8.     @Override  
  9.     public void method1() {  
  10.         System.out.println("productB1-method1");  
  11.     }  
  12.   
  13.     @Override  
  14.     public void method2() {  
  15.         System.out.println("productB1-method2");  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 产品A系列的另一种具体实现:ProductA2 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ProductA2 implements IProductA{  
  7.   
  8.     @Override  
  9.     public void method1() {  
  10.         System.out.println("productA2-method1");  
  11.     }  
  12.   
  13.     @Override  
  14.     public void method2() {  
  15.         System.out.println("productA2-method2");  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 产品B系列的另一种具体实现:ProductB2 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class ProductB2 implements IProductB{  
  7.   
  8.     @Override  
  9.     public void method1() {  
  10.         System.out.println("productB2-method1");  
  11.     }  
  12.   
  13.     @Override  
  14.     public void method2() {  
  15.         System.out.println("productB2-method2");  
  16.     }  
  17.   
  18. }  
[java] view plain copy
  1. /** 
  2.  * 客户端代码,抽象工厂和抽象产品接口的使用者 
  3.  * @author qbg 
  4.  * 
  5.  */  
  6. public class Client {  
  7.     private IFactory factory;  
  8.     private IProductA productA;  
  9.     private IProductB productB;  
  10.       
  11.     public Client(IFactory factory){  
  12.         this.factory = factory;  
  13.     }  
  14.       
  15.     public void product(){  
  16.         productA = factory.createProductA();  
  17.         productB = factory.createProProductB();  
  18.     }  
  19.       
  20.     public void consumeProductA(){  
  21.         productA.method1();  
  22.         productA.method2();  
  23.     }  
  24.       
  25.     public void consumeProductB(){  
  26.         productB.method1();  
  27.         productB.method2();  
  28.     }  
  29.       
  30.     public static void main(String[] args) {  
  31.         //生产消费1系列A,B产品  
  32.         Client c1 = new Client(new ConcreteFactory1());  
  33.         c1.product();  
  34.         c1.consumeProductA();  
  35.         c1.consumeProductB();  
  36.         //生产消费2系列A,B产品  
  37.         Client c2 = new Client(new ConcreteFactory2());  
  38.         c2.product();  
  39.         c2.consumeProductA();  
  40.         c2.consumeProductB();  
  41.     }  
  42. }  

运行结果:

[plain] view plain copy
  1. 生产消费1系列A,B产品  
  2. productA1-method1  
  3. productA1-method2  
  4. productB1-method1  
  5. productB1-method2  
  6. 生产消费2系列A,B产品  
  7. productA2-method1  
  8. productA2-method2  
  9. productB2-method1  
  10. productB2-method2  

四、模式优缺点

优点:

1、分离具体实现,面向接口编程。客户端代码只需访问抽象接口而不需关心具体的实现类,解耦。

2、易于交换产品系列。由于抽象工厂为产品系列提供了统一的抽象层,所以如果想交换产品系列,只需交换相应的具体实现。

3、有利于产品的一致性,这得力于抽象工厂提供的一致抽象。

缺点:

1、难以支持新种类的产品。如果在现有产品系列中添加新的产品,那就要修改现有产品系列的抽象工厂接口,这样必然引起各产品系列抽象工厂的具体实现需要改变。

原创粉丝点击