zoukankan      html  css  js  c++  java
  • 每天一个设计模式(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

  • 相关阅读:
    C# Sleep延时方法
    浅谈模糊测试
    python time模块常用方法小结
    Markdown使用小结
    关于测试用例设计、评审及用例质量评估的思考
    关于评估软件产品质量的思考
    关于软件测试工程师进阶提升的思考
    关于软件测试中回归测试的思考
    测试技术的思考 ---- 读《微软的软件测试之道》有感系列
    vue-learning:22
  • 原文地址:https://www.cnblogs.com/Eason-S/p/5682480.html
Copyright © 2011-2022 走看看