• 抽象工厂模式


    一 、引入

      前面我们讨论了“简单工厂模式”和“工厂方法模式”,这次我们来学习设计模式中最后的一种工厂模式——抽象工厂模式。

      抽象工厂模式其实是工厂方法模式的一种扩展,应用抽象工厂模式可以创建一系列的产品(产品族),而不是像工厂方法模式中的只能创建一种产品。先我们来看一下抽象工厂模式的标准定义:

      抽象工厂模式定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

      官方的定义一般都不易理解,我们就来模拟一个场景来说明一下这其中的关系吧。

      富士康公司给两个品牌作代工产品:苹果和三星。众所周知,这两个品牌都有手机和平板产品,由于生产工艺的不同,富士康开设了两条生产线,一条线只生产手机,另一条线只生产平板,总负责人是车间主任老王。一个卖苹果设备的采购商找到老王,说先给我来1台苹果的iPad, 老王转身到生产平板的生产线上的操作台,往电脑里输入“苹果牌”三个字,很快1台iPad生产出来了。采购商又说,再给我来1台苹果的iPhone吧,老王又转身到手机的生产线,在电脑里输入“苹果牌”,很快一台iPhone又造好了。

      看出来了吗?这里有两种抽象的产品(苹果产品和三星产品),而每种抽象的产品都有两种产品角色(手机和平板电脑),这样就要建立两种工厂(手机工厂和平板工厂)分别负责不同产品角色的实例化。 老王就是工厂的总接口,他负责帮你找到正确的生产工厂,并且拿到你想要的那一种类型的产品。

      每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构。有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。每一个产品等级结构中有多少个具体的产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。总结一下我认为可以应用到抽象工厂模式的实际例子:

    1. 两种产品:PC和MAC,两种产品等级:RAM,CPU

    2. 两种产品:水果和蔬菜,两种产品等级:南方特产,北方特产

    3. 两种产品:男人和女人,三种产品等级:黄种人,黑人,白人

    就类似这种结构的对象关系都可以用抽象工厂模式来构造。。。。。

    二、类图

       下面是从百度百科里引用的类图。

    三、代码会说话

       用简单的代码来说明

    复制代码
    
     1     /// <summary>
     2     /// 苹果产品系列
     3     /// </summary>
     4     public interface Apple
     5     {
     6         void AppleStyle();
     7     }
     8 
     9     /// <summary>
    10     /// 三星产品系列
    11     /// </summary>
    12     public interface Sumsung
    13     {
    14         void BangziStyle();
    15     }
    16 
    17     public class iphone : Apple
    18     {
    19         public void AppleStyle()
    20         {
    21             Console.WriteLine("Apple's style: iPhone!");
    22         }
    23     }
    24 
    25     public class ipad : Apple
    26     {
    27 
    28         public void AppleStyle()
    29         {
    30             Console.WriteLine("Apple's style: iPad!");
    31         }
    32 
    33     }
    34 
    35     public class note2 : Sumsung
    36     {
    37         public void BangziStyle()
    38         {
    39             Console.WriteLine("Bangzi's style : Note2!");
    40         }
    41 
    42     }
    43 
    44     public class Tabs : Sumsung
    45     {
    46         public void BangziStyle()
    47         {
    48             Console.WriteLine("Bangzi's style : Tab!");
    49         }
    50     }
    51 
    52     public interface Factory
    53     {
    54         Apple createAppleProduct();
    55         Sumsung createSumsungProduct();
    56     }
    57 
    58     /// <summary>
    59     /// 手机工厂
    60     /// </summary>
    61     public class Factory_Phone : Factory
    62     {
    63         public Apple createAppleProduct()
    64         {
    65             return new iphone();
    66         }
    67 
    68         public Sumsung createSumsungProduct()
    69         {
    70             return new note2();
    71         }
    72     }
    73 
    74     /// <summary>
    75     /// 平板工厂
    76     /// </summary>
    77     public class Factory_Pad : Factory
    78     {
    79         public Apple createAppleProduct()
    80         {
    81             return new ipad();
    82         }
    83 
    84         public Sumsung createSumsungProduct()
    85         {
    86             return new Tabs();
    87         }
    88     }
    复制代码

       模拟调用过程。

    复制代码
     1         public static void Main(string[] args)
     2         {
     3             //采购商要一台iPad和一台Tab
     4             Factory factory = new Factory_Pad();
     5             Apple apple = factory.createAppleProduct();
     6             apple.AppleStyle();
     7             Sumsung sumsung = factory.createSumsungProduct();
     8             sumsung.BangziStyle();
     9 
    10             //采购商又要一台iPhone和一台Note2
    11             factory = new Factory_Phone();
    12             apple = factory.createAppleProduct();
    13             apple.AppleStyle();
    14             sumsung = factory.createSumsungProduct();
    15             sumsung.BangziStyle();
    16 
    17             Console.ReadKey();
    18         }
    复制代码

       运行结果:

    四、总结 

      抽象工厂模式最大的缺点就是对产品族的扩展非常困难,如果要添加一个新的品牌联想的话,看看我们的改动会有多大吧。。。。 首先要在Factory接口中声明新方法

      Lenovo createLenovoProduct()

      然后在所有现有的工厂实现类中分别实现这个新的createLenovoProduct()方法,如果工厂类有很多,改动的地方也会很多的。。违反了开闭原则,并且作为契约的接口修改了,其他所有和接口有关的代码可能都要改。

      反过来想,如果对产品角色扩展难不难呢?比如我要添加一个新的角色“电脑”,改动的地方有多少呢?只需要新建的各品牌电脑产品类和一个电脑工厂而已,都是扩展而不是修改,这样就又符合了开闭原则。所以说,抽象工厂模式对于产品角色的扩展是很容易的

      到本章为止,设计模式中的所有工厂类的模式就都介绍完啦~ 边学边教,难免会有理解错误的地方,请大家帮我指正~

  • 相关阅读:
    进程和线程
    vue程序搭建
    EXTJS 不显示窗体 标题框的办法
    asp.net 本地资源连接没反映的解决办法
    IIS支持flv格式流传送的办法(解决flash播放器报200错误)
    response.write不要放到try里去,不然会报一个错误 a instance object什么的
    Webservice 用http get方式无法请求到的解决办法
    转一篇关于RIA的内存泄露的文章
    jquery的选择器$('')在IE6下对JS动态生成(比如ajax生成的)的元素失效的解决办法
    聚类存储过程分析
  • 原文地址:https://www.cnblogs.com/toddzhang/p/3392555.html
Copyright © 2020-2023  润新知