概述:
在软件开发中我们常常遇到这样的问题,在一个系统中有多个子系统,而一个应用型的类(客户类)需要和各个子系统打交道来完成一件事情,这样客户代码就会和子系统类耦合。在生活中我们也会遇到这样的问题,打个比方:买房子。我在买房子的时候首先是选,到一个房产开发商那里有售楼小姐给你做介绍,你选中好房子后要办理贷款,签合同,办贷款的时候还要咨询贷款额度,让公司开收入证明,还款类型,指定贷款年。然后还要到售楼处去办理定金,一星期内还要交首付。在这个过程中我要和售楼小姐、我所在的公司、银行,售楼出出纳员,售楼经理好多人打交道,大家试想下如果这个就是一个系统的业务流程那么作为我(用户)需要和这个系统中的子系统多次打交道,这样就形成了客户程序与复杂的系统内部子系统间的紧耦合,从而导致客户程序随着子系统变化而变化。那如何简化客户程序和子系统间的交互呢,这里我们需要再添加一个买房统一接口类(SellMan),帮我做买房的事情这样客户程序(我)不再依赖系统中的子系统。这就是外观模式。看下图:
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 296.25pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5CFANWEI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.emz" o:title=""></imagedata></shape>
解释:
1. 定义一个IBack接口创建PutOUt 放款方法
2. 定义一个IAccountCredit接口创建HasGoodCredit 判断是否可以贷款方法
3. 定义一个Back银行的抽象类,继承IBack,IAccountCredit接口
4. 定义工商(BusinessBack)、农业(AgroBack)、建设(ConstructBack)、交通(TranfficBack)四大银行继承自Back
5. 定义一个ISell接口创建Sell 卖房方法
6. 创建LandAgent房产商继承ISell接口
7. 创建House房屋类
8. 定义一个IBuyHouse接口创建Buy 买房方法
9. 创建SellMan买房屋代理人
10. 创建Client买房人
这样一来客户程序和子系统的通信有中间的SellMan统一协调,通过SellMan的Buy接口做买卖,这样就实现了解耦合。来看看他的客户端的代码把,如此简单:
Client client = new Client();
client.Name = "范伟伟";
client.CreditCount = 500000;
SellMan sell = new SellMan(client);
House house=sell.Buy(100000);
if (house != null)
Console.WriteLine(string.Format("{0}将{1}房屋卖给了{2}", sell.LandAgent.Name, house.ID, client.Name));
else
Console.WriteLine("交易失败");
效果:
OOD设计合理性:
1. 是否符合开不原则:
客户程序和子系统的通信有中间的SellMan统一协调,通过SellMan的Buy接口做买卖,再做修改时只要修改SellMan Buy 方法或再创建一个继承了Buy接口的类
符合
2. 是否符合里氏代换:
符合
3. 是否符合抽象原则
符合
4. 是否符合迪米特法则
符合
装饰模式总结
意图:
为子系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得子系统更加容易操作
结构图:
<shape id="_x0000_i1026" style="WIDTH: 191.25pt; HEIGHT: 204.75pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CFANWEI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.gif" o:href="资料/设计模式(15)-Facade%20Pattern%20-%20First%20we%20try,%20then%20we%20trust%20-%20博客园_files/Pic90.gif"></imagedata></shape>
门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
子系统(subsystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
使用背静:
1. 为一个复杂系统提供一个简单的统一的接口
2. 客户程序与抽象类的实现部分之间存在着很大的依赖性
3. 当需要构建一个层次结构的子系统时,使用外观模式定义子系统中每层的入口点。
模式优缺点:
优点:
1. 他对客户屏蔽了系统组件,因此减少了客户处理的对象的数目并使得子系统使用起来更加方便
2. 使得子系统与客户程序间的松耦合
3. 他并不限制他们使用子系统类,你可以在系统易用性和通用性之间加以斟酌。
注意:
1. 降低客户-子系统之间的耦合度。
用抽象类实现Façade而他的具体子类对应于不同的子系统实现,这可以进一步降低客户与子系统的耦合度。(这里SellMan我没有用抽象类是因为我只为买卖这一层做Facade)。这样,客户就可以通过抽象的Façade类接口与子系统通讯。这种抽象耦合关系使得客户不知道它使用的是子系统的哪一个实现
除了生成子类的方法外,另一种方法是用不同的子系统对象配置Façade对象。为定制façade,近需对他的子系统(一个或多个)进行替换即可。
2. 公共子系统类与私有子系统类
C#不支持私有接口的实现所以这里不多讲
源代码
下载
分享到:
相关推荐
设计模式面面观(13):外观模式(Facade Pattern)-结构型模式 http://blog.csdn.net/fanweiwei/archive/2008/04/17/2299641.aspx
设计模式面面观(14):享元模式(Facade Pattern)-结构型模式 http://blog.csdn.net/fanweiwei/archive/2008/04/25/2326692.aspx
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
36种最新设计模式整理 Design Pattern: Simple Factory 模式 Design Pattern: Abstract Factory 模式 Design Pattern: Builder 模式 Design Pattern: Factory Method 模式 Design Pattern: Prototype 模式 ...
C#面向对象设计模式纵横谈(11):Facade 外观模式(结构型模式) (Level 300)
C#面向对象设计模式纵横谈(11):Facade 外观模式(结构型模式)
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
扩展系统功能——装饰模式(三) 扩展系统功能——装饰模式(四) 外观模式-Facade Pattern 深入浅出外观模式(一) 深入浅出外观模式(二) 深入浅出外观模式(三) 享元模式-Flyweight Pattern 实现对象的复用——...
设计模式(15)-Facade Pattern 设计模式(14)-Flyweight Pattern C#设计模式(13)-Proxy Pattern C#设计模式(12)-Decorator Pattern C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter ...
在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第11节:结构型模式Facade外观模式
c++设计模式-结构型模式-外观模式;qt工程;c++简单源码; 外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,...
facade-design-pattern-in-php:学习PHP中的外观设计模式
本文实例讲述了PHP设计模式:外观模式Facade。分享给大家供大家参考,具体如下: 1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度...
C#面向对象设计模式纵横谈\C#面向对象设计模式纵横谈\10.Facade 外观模式(结构型模式).wmv )
外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: ...
外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型: 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者...
模式定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观...
4.5 facade(外观)—对象结构型 模式 121 4.6 flyweight(享元)—对象结构型 模式 128 4.7 proxy(代理)—对象结构型 模式 137 4.8 结构型模式的讨论 144 4.8.1 adapter与bridge 144 4.8.2 composite、...
C#面向对象设计模式纵横谈(11):Facade 外观模式(结构型模式) C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) C#面向对象设计模式...
本资源是用VC6.0实现的结构型设计模式,主要有BridgePattern、AdapterPattern、DecoratorPattern、CompositePattern、FlyweightPattern、FacadePattern、ProxyPattern六种模式,参考于《23种设计模式(C++).pdf》