前言
在学习这个模式的时候小猪有这样的感觉:我们很多时候会把设计模式想的多么高深,多么的深不可测,新手完全看不懂之类的话,其实只要我们把面向对象基础打好,在写代码的时候会不自不觉的用到一些设计模式,只是我们不知道它叫什么名字而已。
模式定义
外观模式(Facade),为子系统中的一组接口提供了一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
实现代码
代码清单一:子系统的类
class SubSystemOne { public void MethodOne() { Console.WriteLine(" 子系统方法一"); } } class SubSystemTwo { public void MethodTwo() { Console.WriteLine(" 子系统方法二"); } } class SubSystemThree { public void MethodThree() { Console.WriteLine(" 子系统方法三"); } } class SubSystemFour { public void MethodFour() { Console.WriteLine(" 子系统方法四"); } }
代码清单二:外观类
class Facade { SubSystemOne one; SubSystemTwo two; SubSystemThree three; SubSystemFour four; public Facade() { one = new SubSystemOne(); two = new SubSystemTwo(); three = new SubSystemThree(); four = new SubSystemFour(); } public void MethodA() { Console.WriteLine(" 方法组A() ---- "); one.MethodOne(); two.MethodTwo(); four.MethodFour(); } public void MethodB() { Console.WriteLine(" 方法组B() ---- "); two.MethodTwo(); three.MethodThree(); } }
代码清单三:客户端调用
class Program { static void Main(string[] args) { Facade facade = new Facade(); facade.MethodA(); facade.MethodB(); Console.Read(); } }
对于面向对象有一定基础的同学,即使没有听说过门面(外观)模式,也完全由可能在很多时候使用它,因为它完美体现了依赖倒转原则和迪米特法则的思想,所以是非常常用的模式之一。
举个例子:很多人喜欢炒股票,但凡是个有心眼的人都知道:股市有风险、入股需谨慎。自己直接买股票就是客户端直接与大量股票打交道,这在写程序时叫做:耦合度太高。但是这个时候我们发现有一个叫做“基金”的东西。我们只需要来买基金,这个基金来买什么股票我们不关心也不需要了解,客户端买基金之后就可以回家睡觉打麻将了,而买股票这种专业的东西让卖基金的人去搞,这样我们就去除了客户端与股票的耦合。这就是门面(外观)模式的思想。
在具一个例子:添加事件标准浏览器使用addEventListener,旧版本IE使用attachEvent,可能自己需要封装一个addEvent函数,这个addEvent函数就是一个门面。
代码清单四:
function addEvent(el, type, fn) { if (el.addEventListener) { el.addEventListener(type, fn, false) } else if (el.attachEvent) { el.attachEvent('on' + type, fn) } else { el['on' + type] = fn } }
这样我们再给对象添加事件的时候就不需要考虑客户端到底是什么浏览器而直接使用addEvent方法了。
适用场合
对于那些反复同时出现的代码,如函数a和b多次同时出现在代码中,应考虑将a,b组合起来放到一个新函数中。
优点
简化了一些复杂接口(如$.ajax, $.event.add),清除不再需要的大对象以及提供一种更加单一,便利的方式展现接口功能。编写一次组合代码,就可以反复使用它,节省了代码量,时间和精力。它还提供了较高层的功能,抽象,降低客户端代码对底层接口的耦合。如$.getJSON,通过$.ajax方法也可以得到相同的效果。但每次都需要配置相同的参数,如果获取JSON的需求很频繁,页面中的相同的代码就需要写很多次。而封装一次$.getJSON,之后就少写很多代码,且该方法更直观。
缺点
外观模式并非必不可少,同样的功能不使用它也能完成功能。如不使用$.getJSON,通过$.ajax方法也可以得到相同的效果。此外由于增加了一层闭包,性能会有一定降低。