大熊君说说JS与设计模式之(门面模式Facade)迪米特法则的救赎篇------(监狱的故事)
一,总体概要
1,笔者浅谈
说起“门面”这个设计模式其实不论新老程序猿都是在无意中就已经运用到此模式了,就像我们美丽的JS程序员一样不经意就使用了闭包处理问题,
function Employee(name) {
var name = name;
this.say = function () {
console.log("I am employee " + name) ;
} ;
}
代码中“say”是一个function,Employee也是一个function这就构成了一个闭包环境,其实多数我们都是如上的定义方式,也就潜移默化的使用了闭包,O(∩_∩)O~ 让我们继续回来,门面这个模式很容易理解见如下图

图中描述的很清晰,三个子系统彼此独立有自己的职责划分,从客户端的角度来看是不关心它们细节的,那么如何把这三个子系统与客户端做连线那?好的!!!这时文中的主角该亮相了,这就是门面模式它起到了一个统一入口的职责,
降低子系统之间客户端与实现化层之间的依赖性。当在构建一个层次化的系统时,也可以同过使用Facade模式定义系统中每一层的入口,从而简化层与层之 间的依赖关系。
文字可能会有些抽象但是慢慢来,一步步分析,现在假设有这么个场景,有两个以完善的插件模块,基于这个再做二次开发,我们想想这就和图中的场景很类似了,以下是模拟代码有助于理解
function HelloWorld(){
this.greetPlug = new GreetPlug() ;
this.filterPlug = new FilterPlug() ;
this.hello = function(name){
if(!this.filterPlug.filter(name,"zhangsan")){
this.greetPlug().say(name) ;
}
}
} ;
function GreetPlug(){
this.say = function(what){
console.log("Hello," + what) ;
}
} ;
function FilterPlug(){
this.filter = function(what,not){
return (what === not) ? true : false ;
}
} ;
里面的HelloEorld就是相对于和门面接口,至于两外两个类是隐藏的,这就是大概的思路!再看两个应用例子加深理解,如下图

隐藏了DOM标准事件接口的细节,做了事件兼容的api。

这个大家就更熟悉了,jQuery的Ajax操作是大家平时操作相对来说比较频繁的,没错它也用到了门面模式,底层是低级api做支持,门面层通过不同参数划分职能!
二,门面与迪米特法则
迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文简写为: LoD.
迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用性才可以提高。
其实二者的关系很好理解,门面模式就是基于此法则衍生出来的解决方案,适用于特定场景的同一类问题的解决方案。下面再来看个例子,如下
现在有这么个场景------监狱内的犯人是不应该跟外面的人接触的,当然或许会有探亲的。这里的监狱就是类,里面的犯人就是类内部的信息,而监狱里的狱警就相当于迪米特法则的执行者
function Inmates(){
this.say = function(){
console.log('狱友说:我们是狱友...") ;
} ;
} ;
function Prisoners(){
this.inmates = new Inmates() ;
this.helpEachOther = function(){
this.inmates.say() ;
console.log("家人说:你和狱友之间应该互相帮助...") ;
} ;
} ;
function Family(){
this.prisoners = new Prisoners() ;
this.visit = function(inmates,prisoners){
this.prisoners.helpEachOther() ;
} ;
} ;
看到这样的结果,是不是有些别扭,家人告诉犯人要与狱友好好相处,而狱友确冒出来说话。这显然越界了,因为监狱只允许家人探望犯人,而不是随便谁都可以见的
这里的家人和狱友有了沟通是违背迪米特法则的,所以我们需要将家人和狱友隔离开,对其进行重构
(1),定义家人类
function Family(){
this.prisoners = new Prisoners() ;
this.visit = function(prisoners){
console.log("家人说:") ;
this.prisoners.helpEachOther() ;
} ;
} ;
(2),定义犯人类
function Prisoners(){
this.inmates = new Inmates() ;
this.helpEachOther = function(){
console.log("犯人和狱友之间应该互相帮助...") ;
console.log("犯人说:") ;
inmates.weAreFriends() ;
} ;
} ;
(3),定义狱友类
function Inmates(){
this.weAreFriends = function(){
console.log('我们是狱友...") ;
} ;
} ;
(4),定义场景类
function Prison(){ new Family().visit(new Prisoners()) ; } ;
这样家人和狱友就分开了,但是也表达了家人希望狱友能跟犯人互相帮助的意愿。也就是两个类通过第三个类实现信息传递
三,概要总结
迪米特法则的总结:
迪米特法则不希望类直接建立直接的接触。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,
这些类之所以存在完全是为了传递类之间的相互调用关系------这在一定程度上增加了系统的复杂度。有兴趣可以研究一下设计模式的门面模式(Facade)和中介模式(Mediator),
都是迪米特法则应用的例子。
门面模式的优点:
松散耦合
门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
简单易用
门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。
更好的划分访问层次
通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。
哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步(*^__^*) 嘻嘻……
大熊君说说JS与设计模式之(门面模式Facade)迪米特法则的救赎篇------(监狱的故事)的更多相关文章
- 大熊君说说JS与设计模式之------代理模式Proxy
一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一 ...
- 大熊君说说JS与设计模式之------状态模式State
一,总体概要 1,笔者浅谈 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...
- 大熊君说说JS与设计模式之------命令模式Command
一,总体概要 1,笔者浅谈 日常生活中,我们在看电视的时候,通过遥控器选择我们喜欢的频道时,此时我们就是客户端的角色,遥控器的按钮相当于客户请求,而具体执行的对象就是命令对象, 命令模式把一个请求或者 ...
- 大熊君说说JS与设计模式之------策略模式Strategy
一,总体概要 1,笔者浅谈 策略模式,又叫算法簇模式,就是定义了不同的算法,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式和工厂模式有一定的类似,策略模式相对简单容易理解,并 ...
- 大熊君说说JS与设计模式之------中介者模式Mediator
一,总体概要 1,笔者浅谈 我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介.租房者并不关心他租谁的房.房东出租者也不关心他租给谁.因为有中介的存在 ...
- 大熊君说说JS与设计模式之------单例模式Singleton()
一,总体概要 1,笔者浅谈 顾名思义单例模式并不难理解,是产生一个类的唯一实例,在我们实际开发中也会使用到这种模式,它属于创建模式的一种,基于JS语言本身的语法特征, 对象直接量“{}”,也可以作为单 ...
- JavaScript设计模式(6)-门面模式
门面模式 门面模式(Facade Pattern):他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口.这种类型的设计模式属于结构性模式.为子系统中的一组接口提供了一个统一的访问接口,这个接 ...
- 外观模式 门面模式 Facade 结构型 设计模式(十三)
外观模式(FACADE) 又称为门面模式 意图 为子系统中的一组接口提供一个一致的界面 Facade模式定义了一个高层接口,这一接口使得这一子系统更加易于使用. 意图解析 随着项目的持续发展,系统 ...
- python 设计模式之门面模式
facade:建筑物的表面 门面模式是一个软件工程设计模式,主要用于面向对象编程. 一个门面可以看作是为大段代码提供简单接口的对象,就像类库. 门面模式被归入建筑设计模式.门面模式隐藏系统内部的细 ...
随机推荐
- HP XP7 GAD双活实现的理解
XP7双活的虚拟卷global active device (GAD)实际上对应两个存储的两个物理卷(有点儿像Mirror Disk镜像) 当主机A向阵列A发出写数据请求后,阵列A首先检查要被写入的数 ...
- PHP面向对象的标准
(1)所有数据都应该隐藏在所在的类的内部. (2)类的使用者必须依赖类的共有接口,但类不能依赖它的使用者. (3)尽量减少类的协议中的消息. (4)实现所有类都理解的最基本公有接口[例如,拷贝操作(深 ...
- PHP 判断是否为Get/Post/Ajax提交
<?php PHP 判断是否为Get/Post/Ajax提交 /** * 是否是AJAx提交的 * @return bool */ function isAjax(){ if(isset($_S ...
- springMVC配置(XML配置详解)
原文出自:http://www.newasp.net/tech/71609.html web.xml配置: servlet> <servlet-name>dispatcher< ...
- hdu 3999 The order of a Tree (二叉搜索树)
/****************************************************************** 题目: The order of a Tree(hdu 3999 ...
- C# 编程指南-事件
来自微软官方的msdn: 首页:https://msdn.microsoft.com/zh-cn/library/ms366768.aspx 1.如何:订阅和取消订阅事件 2.如何:发布符 ...
- 安装 composer SSL operation failed with code 1
gavin@webdev:~> curl -sS https://getcomposer.org/installer | php Downloading... Download failed: ...
- XE随想4:SuperObject增、删、改
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- iOS从不同页面跳转回到指定控制器
HomeViewController *homeVC = [[HomeViewController alloc] init]; UIViewController *target = nil; for ...
- python学习之路-day4-装饰器&json&pickle
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 一.生成器 1.列表生成式 >>> L = [x * x for x in range(10 ...