Design Pattern – Proxy, Adapter, Facade, Mediator

这几个模式比较类似, 都是用作interface, 但有所不同 
Proxy, 特点是以假乱真, client在使用的时候就和在使用真正的object一样, 接口完全一致, proxy和object的交互是对client透明的 
Adapter, 典型的是电源的adapter, 美标换欧标, 即解决接口不匹配, client和lib都已经写好, 但接口不匹配 
Facade, 用于屏蔽子系统的细节, 提供高层接口层 
Mediator, 典型的房产中介, 当对象之间关系复杂的时候, 避免对象之间的直接沟通

其中Adapter和Facade是在不得已的情况下采用的, 即已有legacy的系统, 很难改变的情况下的折衷方案

 

代理模式

代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 
场景, 在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象. 
这个模式很容易理解, 而且实际应用很多, 如 
远程(Remote)代理, 典型的例子, webservice远程调用, RPC 
保护(Protect or Access)代理, 控制访问权限 
虚拟(Virtual)代理, 当创建消耗资源很大的对象时使用, 如打开很多图片的Html, 会先显示文字, 而图片会下载结束后才显示, 那些未打开的图片框就是用虚拟代理来替代真实图片. 
智能引用(Smart Reference)代理:代理需要处理一些额外的事, 如引用计数, 计数为0时释放引用等. 
可见这个模式虽然简单, 但是还是很有用的, 代理提供了一层封装, 使客户在访问到真正对象前, 可以做预先的处理, 灵活性很大.

如下图, Subject类定义了RealSubject和Proxy公共的接口, 这样在任何使用RealSubject的地方都可以使用Proxy 

class RealSubject : Subject
{
    void Request() { print("Real request");}
}

class Proxy : Subject
{
    RealSubject realSub; //真实对象
    void request() { realSub.Request(); } //可以在访问真实对象时, 添加任何逻辑
} 

用户使用直接访问代理 

Proxy p = new Proxy()
p.Request()

 

 

门面模式

门面模式 (facade)又称外观模式, 为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 
这个模式很简单, 当子系统接口比较复杂时, 如果让客户直接使用子系统接口, 有如下问题,  
系统难于使用, 客户需要先熟悉复杂的子系统接口 
耦合度过高, 当子系统改变时, 会影响到客户类  
这样明显违反了迪米特法则和依赖倒转法则, 所以我们的做法就是提供一个相对简单的高层抽象接口来屏蔽底层子系统的细节,从而解决了上面两个问题. 
这个模式很简单, 也很常用, 无论你是否知道这个模式

 

 

适配器模式

适配器模式 (Adapter), 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 
这个模式很简单, 一般用于对已有系统的porting和重用. 这个模式应该是不得已而为之, 因为直接改变原来系统的接口肯定不合适, 所以为了可以重用这个系统必须增加一层adapter.

 

中介者模式

中介者模式(Mediator), 用一个中介对象来封装一系列的对象交互. 中介者使各对象不需要显式地相互引用, 从而使其耦合松散, 而且可以独立地改变它们之间的交互.

这个模式很好理解, 如房产中介, 留学中介, 当然最大的中介者,联合国. 中介的目的就是解耦合, 使得可以独立地改变和复用各个同事对象和中介者类.

 

对于面向对象设计, 需要将系统分割成许多对象以增加复用性, 但是对象间激增的相互关联有大大降低了其复用性, 大量的关联导致对象间紧耦合, 修改一个对象就会导致所有和该对象相关联的对象的改动, 牵一发而动全身.  
但是面对这种情况, 首先想到的不应该是用中介者模式, 而是系统设计不合理, 设计时应尽量的高聚合低耦合, 而对象间大量的关联导致高耦合, 很有可能是设计不合理, 系统分割过细导致的, 一般通过重新设计就可以解决. 
中介者模式适用于, 对象间关系确实很复杂, 如联合国, 各国间关系错综复杂, 于是需要一个中介者把对象间复杂的交换剥离出来交给中介者来处理. 
这个模式的缺点就是, 由于把所有对象间交换集中在中介者, 会导致中介者逻辑会过于复杂.

 

class ConcreteMediator : Mediator
{
    //中介者需要认识所有的同事对象
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public override void Send(string message,Colleague colleague)
    {
        //根据各种条件在不同的同事对象间经行交互
        //这段逻辑往往会变的很复杂
        if (colleague == colleague1)
        {
            colleague2.Notify(message);
        }
        else
        {
            colleague1.Notify(message);
        }
    }
} 

class ConcreteColleague1 : Colleague
{
    protected Mediator mediator; //同事对象只需要认识中介者, 而不需要认识其他任何同事

    // Constructor
    public ConcreteColleague1(Mediator mediator) : base(mediator)
    {
    }

    public void Send(string message)
    {
        mediator.Send(message, this); //需要和其他同事交互时, 通过中介者
    }

    public void Notify(string message) //提供给中介者的交互接口
    {
        Console.WriteLine("Colleague1 gets message: "+ message);
    }
}

//客户代码
ConcreteMediator m = new ConcreteMediator();
ConcreteColleague1 c1 = new ConcreteColleague1(m);
ConcreteColleague2 c2 = new ConcreteColleague2(m);

m.Colleague1 = c1;
m.Colleague2 = c2;

c1.Send("How are you?");
c2.Send("Fine, thanks");

本文章摘自博客园,原文发布日期:2013-11-19
时间: 2024-11-07 15:53:07

Design Pattern – Proxy, Adapter, Facade, Mediator的相关文章

Design Pattern: Proxy 模式

学习是分享和合作式的! 转载请注明出处:http://blog.csdn.net/wdzxl198/article/details/10472999: 文章摘自: http://www.riabook.cn/doc/designpattern/: 在 Gof 的书中对Proxy模式的目的给定为:为其它的物件提供一种代理,以控制对这个物件的访问.由这句话所延伸出来的意思是,根据您的目的不同,您的代理物件将负有不同的责任,因为产生多种不同的代理情况. 根据不同的代理目的,而有不同的代理情况,在Gof

Design Pattern: Default Adapter 模式

在Java中如果要定义事件处理的方式,必须实作EventListener的子介面,例如实作 WindowListener来定义一些视窗事件的处理方式,WindowListener中定义了七个方法: public interface WindowListener extends EventListener { public void windowOpened(WindowEvent e); public void windowClosing(WindowEvent e); public void

我的Design Pattern之旅[7]:使用泛型改進Adapter Pattern(OO)

Introduction 在(原创) 我的Design Pattern之旅[6] : Adapter Pattern (OO) (Design Pattern) (C/C++) (.NET) (C#) (C++/CLI) (VB) 中的Grapher范例,我们看到Class Adapter必须针对Triangle.Circle.Square量身订做TriangleDrawAdapter.CircleDrawAdapter.SquareDrawAdapter,虽然符合OCP,但每个class就得需

我的Design Pattern之旅[4]:使用Generic改進Strategy Pattern(OO)

Abstract 在(原创) 我的Design Pattern之旅:使用template改进Strategy Pattern (OO) (Design Pattern) (C/C++) (template)中,使用了C++的template改进strategy pattern,本文使用C#的generic改进strategy pattern. Introduction C# 2.0加入了generic对泛型的支援,所以想将原来C++的template程式一行一行的改成C# generic. 在s

我的Design Pattern之旅[3]:使用template改進Strategy Pattern(OO)

在(原创) 我的Design Pattern之旅:Strategy Pattern (初级) (Design Pattern) (C++) (OO C++) (Template C++)中,我们使用了strategy pattern让Grapher能画Triangle.Circle和Square 因为需求再次改变,:D,我们希望Grapher能将文字印在各Shape中,执行结果如下 Draw Hello Shape!! in Square Draw Hello C++!! in Circle 为

Rational:基于Design Pattern Toolkit的开发

1 内容简介 设计模式工具箱(Design Pattern Toolkit)是基于Eclipse的模板引擎,它向用户提供一个模型驱动 的框架,帮助用户简化应用程序的开发.用户通过模板定制应用程序的必要信息,设计模式工具箱帮助用 户自动生成应用程序的所有构件.使用设计模式工具箱将显著的加速常见应用程序的开发,与此同时,设 计模式工具箱向用户提供了构建一类应用程序的最佳实践,因此,使用它将帮助用户分享最佳实践的价值 . 本文首先介绍设计模式的基本概念,然后介绍设计模式工具箱(Design Patte

Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern

   Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming.这其中透露的Monad重要性则不言而喻.Scalaz是通过Monad typeclass为数据运算的程序提供了一套规范的编程方式,如常见的for-comprehension.而不同类型的Monad实例则会支持不同的程序运算行为,如:Option Monad在运算中如果遇到None值则会中途退出:St

Design Pattern: Prototype 模式

  学习是分享和合作式的! 转载请注明出处:http://blog.csdn.net/wdzxl198/article/details/9271773: 文章摘自: http://www.riabook.cn/doc/designpattern/: 您从图书馆的期刊从发现了几篇您感兴趣的文章,由于这是图书馆的书,您不可以直接在书中作记号或写字,所以您将当中您所感兴趣的几个主题影印出来,这下子您就可在影印的文章上画记重点. Prototype模式的作用有些类似上面的描述,您在父类别中定义一个clo

软体样式(Design Pattern )之应用

软体样式(Design Pattern )           之应用 ※ 高焕堂 自从1991年以来╋样式观念和理论逐渐成为物件导向(OO)领域中最热门的话题之一.本文探讨如何使用样式╋解决软体上的常见问题. 什么是样式?      顾名思意╋样式是人们遭遇到特定问题时╋大家惯用的应付方式.样式可用来解决问题╋而且是有效.可靠的.掌握愈多样式╋运用愈成熟╋就愈是杰出的设计专家.    依据样式理论大师亚历山大(Christopher Alexander) 之定义