zoukankan      html  css  js  c++  java
  • 解读设计模式外观模式(Facade Pattern),谈阿牛讨媳妇故事

    一、模式简介

          外观模式(Facade Pattern)可以将一系列复杂的类包装成一个简单的封闭接口。也称门面模式.

    二、模式意图

          每一种设计模式都有它的意图,我们看看设计模式的祖师们是怎么说的。按照GOF的说法,Facade模式的意图是:为了子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

          

    三、模式UML(下图转自http://www.dofactory.com/

                               

     四、模式参与者

          门面(Facade)角色:客户端可以调用这个角色的方法。

              此角色知晓相关的(一个或者多个)子系统的功能和责任。

              在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

              

          子系统(SubSystem)角色:可以同时有一个或者多个子系统。

              实现子系统的功能,处理由Facade对象指派的任务。

              每一个子系统都不是一个单独的类,而是一个类的集合。

              每一个子系统都可以被客户端直接调用,或者被门面角色调用。

              子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

    五、模式的实现

         在做实现之前我们先来分享一个故事《阿牛取媳妇》,传说啊有一个很牛B的人物--阿牛,他不但多妻,还多得很特别.为什么说特别呢?因为他的所有妻子都是亲姐妹.呵呵,这样说来好象是真还有些特别,一个人把一家里的众多女儿都取到手了.实在是强,让人不得不佩服.

         据说,有一个叫赵员外的商人,家里有6个女人,分别叫春香、夏香、秋香、冬香、花花和朵朵。一天一个牛B人(阿牛)出现了,在河边看见这六姐妹洗衣服。所谓英雄难过美人关,一见到其中一个便心动了,什么什么的一见钟情或许就是这样的吧。然后他发现其他的5个是一个比一个漂亮,阿牛便暗地里发誓说:“我一定要将你们几个大美人一并取回家当媳妇”。当阿牛发下誓后便暗地地打听这几个大美人的情况,了解清楚了他便觉定亲自出马去追这几个美人。然后分别将其取回家做媳妇。那阿牛是怎么追的呢?追到一个取回家,然后又追第二个取回家.........是这样的吗?见下图:

                          

    代码实现:

     1 namespace DesignPattern.FacadePattern
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             阿牛 an = new 阿牛();
     8             IList wife = an.GetWife();
     9             for (int i = 0; i < wife.Count; i++)
    10             {
    11                 Console.WriteLine(wife[i].GetType().ToString());
    12             }
    13         }
    14     }
    15 
    16     class 春香 { }
    17     class 夏香 { }
    18     class 秋香 { }
    19     class 冬香 { }
    20     class 花花 { }
    21     class 朵朵 { }
    22 
    23     class 阿牛
    24     {
    25         IList wife = new ArrayList();
    26 
    27         public IList GetWife()
    28         {
    29             //阿牛追春香
    30             wife.Add(new 春香());  //春香同意了,放入老婆队列
    31             wife.Add(new 夏香());
    32             wife.Add(new 秋香());
    33             //其他类似,代码略
    34 
    35             return wife;
    36         }
    37 
    38     }
    39 }

       

         这样,阿牛就可以把赵员外全部的女人都取回家了。可是,在着其中阿牛发现了很大的一个问题,那就是他在反复的做重复的事情,既追美女--美女同意-->取回家当媳妇,追美女--美女同意-->取回家当媳妇......

         在OO的程序设计中,我想大家都比较清楚,我们为什么要使用OO的设计思想,通过OO的设计给我们带来的最大好处是什么?我想“复用”应该是其中一个吧,如上阿牛讨老婆,追到一个美女厚又去追第二个,这样的重复性劳动我们是不是应该想办法来解决呢?如果应用到OO的设计思想,我们应该采取什么要的设计方式来解决呢?

         我想,现在应该就是外观(Facade)模式上场的时候了,阿牛的最终目的是把赵员外的全部女人追到手,然后取回家当媳妇。那么,引入Facade模式,我们应该怎么来处理呢?既然阿牛怎么行,六个女人都可以搞顶,那么让他直接去找赵员外也应该不成问题,让赵员外直接把6个女儿全部嫁给他。

         通过引入Facade模式,改进后的阿牛讨媳妇的设计如下:

                           

         实现思想就是,阿牛要取到赵员外的众多女儿,如果阿牛直接去找其中的一个,然后将其取回家,这样众多的女儿他就要去重复多次相同的动作了。阿牛很聪明,也很自信,他相信怎么多美人都可以搞定,那他一定也能够搞定赵员外这个老头子,如果他便向赵员外提亲,还要求将他的全部女儿都出嫁给他。这样赵员外就充当了一个门面(Facade)角色,众多女儿则是模式参与者中的子系统角色。

         示意性代码如下:

     1 namespace DesignPattern.FacadePattern
     2 {
     3     class FacadeTwo
     4     {
     5         public static void Main(string[] arags)
     6         {
     7             Father facade = new Father();
     8             facade.Married();
     9         }
    10     }
    11 
    12     public class 春香 
    13     {
    14         public void Married()
    15         {
    16             Console.WriteLine("春香出嫁!");
    17         }
    18     }
    19     public class 夏香 
    20     {
    21         public void Married()
    22         {
    23             Console.WriteLine("夏香出嫁!");
    24         }
    25     }
    26     public class 秋香 
    27     {
    28         public void Married()
    29         {
    30             Console.WriteLine("秋香出嫁!");
    31         }
    32     }
    33     public class 冬香 
    34     { 
    35         //此处代码与上基本相似,代码略
    36     }
    37     public class 花花 { }
    38     public class 朵朵 { }
    39 
    40     public class Father
    41     {
    42         private readonly 春香 cx = new 春香();
    43         private readonly 夏香 xx = new 夏香();
    44         private readonly 秋香 qx = new 秋香();
    45         private readonly 冬香 dx = new 冬香();
    46         //..其他的略同,代码省
    47 
    48         public void Married()
    49         {
    50             cx.Married();
    51             xx.Married();
    52             qx.Married();
    53             //..其他的略同,代码省
    54         }
    55     }
    56 }

         这个阿牛真的很强哈,从赵员外手上一下取了六个老婆,佩服,佩服!!!!

    六、协作关系

          客户程序通过发送请求给Facade的方法与子系统通讯,Facade将这些消息转发给适当的子系统对象。尽管是子系统中的有关对象在做实际的工作,但Facade模式本身也必须将它的接口转换成子系统的接口。

          使用Facade的客户程序不需要直接访问子系统对象(父母包办,想娶人家女儿,直接找她老爹商量就OK!)。

    七、相关模式 

          Abstract Factory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abatract Factory模式也可以代替Facade模式隐藏那些与平台相关的类。

          Singleton模式常在Facade模式中出现,每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例(Singleton)模式。但整个系统可以有多个门面类。

          Mediator模式与Facade模式的相似之处是,它抽象了一些已有的类的功能。

    八、参考文献

    Addison-Wesley,1995,p.185. 中文版:《设计模式:可复用的面向对象软件的基础》 李英军等译.

    Alan Sharroway & James r.Trott.中文版:《设计模式精解》 熊节译。

    Jams W.Cooper 著. 《C#设计模式》  张志华 刘云鹏译

    张逸  著《软件设计精要与模式》

    注:转载请注明出处:http://beniao.cnblogs.com/http://www.cnblogs.com/   作者 :Beniao

  • 相关阅读:
    MYSQL基础02DML操作数据8
    MYSQL基础02SQL5
    SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)
    SpringSecurity权限管理系统实战—三、主要页面及接口实现
    SpringSecurity权限管理系统实战—九、数据权限的配置
    SpringSecurity权限管理系统实战—八、AOP 记录用户、异常日志
    SpringSecurity权限管理系统实战—六、SpringSecurity整合JWT
    SpringSecurity权限管理系统实战—二、日志、接口文档等实现
    SpringSecurity权限管理系统实战—五、整合SpringSecurity(下)
    SpringSecurity权限管理系统实战—七、处理一些问题
  • 原文地址:https://www.cnblogs.com/beniao/p/1250823.html
Copyright © 2011-2022 走看看