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");
Design Pattern – Proxy, Adapter, Facade, Mediator的更多相关文章
- [Design Pattern] Proxy Pattern 简单案例
Proxy Pattern, 即代理模式,用一个类代表另一个类的功能,用于隐藏.解耦真正提供功能的类,属于结构类的设计模式. 下面是 代理模式的一个简单案例. Image 定义接口,RealImage ...
- 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验
这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验. 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器.我们用一些前端框架的 ...
- java design pattern - adapter pattern
场景 适配器模式 总结 参考资料 场景 在编程中我们经常会遇到驴头不对马嘴的情况,比如以前是继承A的接口的对象,现在外部调用的时候需要该对象已B接口的形式来调用 ,这个时候我们可以让对象同时集成A和B ...
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 设计模式(Design Pattern)系列之.NET专题
最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...
- [转]Design Pattern Interview Questions - Part 4
Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...
- Design Pattern in Simple Examples
Instead of defining what is design pattern lets define what we mean by design and what we mean by pa ...
- java设计模式大全 Design pattern samples in Java(最经典最全的资料)
java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...
- [转]Design Pattern Interview Questions - Part 1
Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...
随机推荐
- Hadoop-2.4.0分布式安装手冊
文件夹 文件夹 1 1. 前言 2 2. 部署 2 2.1. 机器列表 2 2.2. 主机名 2 2.2.1. 暂时改动主机名 3 2.2.2. 永久改动主机名 3 2.3. 免password登录范 ...
- 【未完成】junit简单使用
参考资料: 一般使用:https://www.w3cschool.cn/junit/ 集成spring: https://www.cnblogs.com/faramita2016/p/7637086. ...
- linux学习笔记6--命令mv
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. mv命令用来对文件或目录重新命名,或者将文 ...
- 初窥XSS跨站脚本攻击
XSS跨站脚本攻击的分类 一. 反射型XSS跨站脚本攻击 二. 存储型XSS跨站脚本攻击 三. 基于DOM的XSS跨站脚本攻击 1.反射性XSS 经过后端,不经过数据库 2.储存型XSS 经过后端,经 ...
- 脚本 sh 和 ./ 的区别,exec和source
如果.不在PATH里面,要执行当前目录下的可执行文件,使用全路径: ./executable-file PATH是环境变量,如果将当前目录“./”添加到环境变量中,那么也可以不用“./”,直接输入当前 ...
- java删除递归文件夹及文件夹下文件
public static void delUrlLocalFile(String urlPath) { File file = new File(urlPath); if(file.isDirect ...
- 【Selenium】之谷歌、IE、火狐浏览器各个版本的浏览器驱动下载地址
地址:chromedriver官网下载地址: http://chromedriver.storage.googleapis.com/index.html(失效了) http://npm.taobao. ...
- Windows下 Zmq v4.0.4的使用 (C++)
最近在研究Zero的使用. 我在网上找了一下,发觉大部分博客都写得乱七八糟,又不写明什么版本,什么系统下的,我都不知道怎么样才能弄出个编译过的程序来,只好自己摸索了. 我是windows下 使用vs2 ...
- php 区分中文,英文,中英混合
$str1="是你"; $strA = trim($str1); $lenA = strlen($strA); $lenB = mb_strlen($strA,"utf- ...
- PAT007 六度空间
“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够 ...