`
wangym
  • 浏览: 123231 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

门面模式(Facade Pattern)

阅读更多

近期参与项目研发,调接口时遇一事不爽,比如在调C方法前必须得先调A方法,成功后再调B方法拿到返回结果后,最后才可以调C方法,而且接口调用还会随需求变化而变更,比如可能还得再增加几个步骤......

 

门面模式(亦称外观模式Facade Pattern)的思想很好地解决了这一问题,当然,它的优点也不止如此。

 

场景举例

 

投递信件的过程是:首先写信的内容 -> 其次写信封 -> 把信放到信封里 -> 然后邮递

 

接口类:ILetterProcess

/**
 * @author xuanyin
 * 
 */
public interface ILetterProcess {

	/**
	 * 首先写信的内容
	 * 
	 * @param context
	 */
	void writeContext(String context);

	/**
	 * 其次写信封
	 * 
	 * @param address
	 */
	void fillEnvelope(String address);

	/**
	 * 把信放到信封里
	 */
	void letterIntoEnvelope();

	/**
	 * 然后邮递
	 */
	void sendLetter();
}

 

实现类:LetterProcess

(代码略)

 

场景类:Client

/**
 * @author xuanyin
 * 
 */
public class Client {

	public static void main(String[] args) {

		// 创建一个处理信件的过程
		ILetterProcess letterProcess = new LetterProcess();
		// 开始写信
		letterProcess.writeContext("context");
		// 开始写信封
		letterProcess.fillEnvelope("address");
		// 把信放到信封,并封装好
		letterProcess.letterIntoEnvelope();
		// 跑到邮局把信塞到邮件,投递
		letterProcess.sendLetter();
	}
}

 

上述过程,与高内聚的要求相差甚远,更不要说迪米特法则、接口隔离原则。调用方首先得知道这四个步骤,而且还不能颠倒顺序。这在面向对象的编程中是极度地不适合的,它根本就没有完成一个类所具有的单一职责。更何况,如果信件多了就非常麻烦,每封信都要这样运转一遍。

 

模式演变

 

增加一邮局类,提供信件代发业务,只需把信件的必要信息告之,就代为发送,即提供以上四个步骤的一体化服务。

 

邮局类:PostOffice

/**
 * @author xuanyin
 * 
 */
public class PostOffice {

	/**
	 * 
	 */
	private ILetterProcess letterProcess = new LetterProcess();

	/**
	 * 写信,封装,投递,一体化了
	 * 
	 * @param context
	 * @param address
	 */
	public void sendLetter(String context, String address) {

		// 帮你写信
		letterProcess.writeContext(context);
		// 写好信封
		letterProcess.fillEnvelope(address);
		// 把信放到信封中
		letterProcess.letterIntoEnvelope();
		// 邮递信件
		letterProcess.sendLetter();
	}
}

 

注意,这个新增加的邮局类就是“门面对象”

 

增加邮局类后,在场景类中调用时就简单多了

 

场景类:Client

/**
 * @author xuanyin
 * 
 */
public class Client {

	public static void main(String[] args) {

		// 现代化邮局
		PostOffice postOffice = new PostOffice();
		// 写完内容和地址后邮局一体化代发,不必关心其中过程
		postOffice.sendLetter("context", "address");
	}
}

 

可以看到,在场景类中的调用简化了很多,只需要把信息提交过去就成了,不必再知道投递过程中的所有方法和顺序了。而且这样做的可扩展性还非常好,比如在非常时期,警察需要对信件进行安全检查,就可以按如下实现。

 

警察类:Police

/**
 * @author xuanyin
 * 
 */
public class Police {

	/**
	 * 警察对信件进行检查
	 * 
	 * @param context
	 * @return true检查通过|false检查不通过
	 */
	public boolean checkLetter(ILetterProcess letterProcess) {

		return true; // or false
	}
}

 

再看下当增加检查信件步骤后,邮局类的一些变更。

 

邮局类:PostOffice

/**
 * @author xuanyin
 * 
 */
public class PostOffice {

	/**
	 * 
	 */
	private ILetterProcess letterProcess = new LetterProcess();

	/**
	 * 
	 */
	private Police police = new Police();

	/**
	 * 写信,封装,投递,一体化了
	 * 
	 * @param context
	 * @param address
	 */
	public void sendLetter(String context, String address) {

		// 帮你写信
		letterProcess.writeContext(context);
		// 写好信封
		letterProcess.fillEnvelope(address);
		// 警察检查信件
		if (police.checkLetter(letterProcess)) {
			// 把信放到信封中
			letterProcess.letterIntoEnvelope();
			// 邮递信件
			letterProcess.sendLetter();
		}
	}
}

 

增加警察检查信件这个逻辑后,并没有改动调用端的代码,也没有改变对外暴露的接口和方法,只是改变内部的处理逻辑,所以对调用端是透明的。这是一个非常棒的设计,这就是门面模式。

 

注意事项

 

一、一个接口类可以用多个门面

 

一般情况下,一个接口类只要有一个门面对象就足够了,但下列情况可以有多个:

 

1.门面对象已庞大到一定的程度:比如超过一定行数的代码,虽然都是非常简单的委托操作,也建议拆分成多个门面。拆分时可按功能拆分,比如一个数据库操作,拆分成查询门面对象,删除门面对象,更新门面对象等。

 

2.给接口类提供不同的访问路径:我的理解是,比如模块1通过门面对象A可以完整地访问所有逻辑,但模块2是受限制的,如果仍使用门面对象A,那是无法实现受限的。这时就需要新增门面对象B,提供模块2应得的方法。但在新增门面对象B时,无需重新实现。因在面向对象编程中,应尽量保持相同的代码只写一遍,避免以后修改时到处都要修改的杯具发生。如:

/**
 * 
 * @author xuanyin
 * 
 */
public class Facade2 {

	// 引用原有的门面
	private Facade1 facade1 = new Facade1();

	/**
	 * 因提供的方法在原有门面中已实现,故此处通过引用,无需重复实现
	 */
	public void methodB() {
		this.facade1.methodB();
	}
}

 

二、门面不参与接口类内的业务逻辑

 

门面对象只是提供一个访问接口的路径而已,不应该也不能参与具体的业务逻辑,否则就会产生一个倒依赖的问题:接口必须依赖门面才能被访问。如果在门面对象内有业务逻辑,则应建立一个封装类,封装完毕后提供给门面对象。

 

 

 

16
1
分享到:
评论
5 楼 shunai 2010-08-25  
dao 这一层是否也类似门面模式
4 楼 navy0168 2010-08-25  
学习了,很形象
3 楼 hunnuxiaobo 2010-08-23  
恩,通俗易懂,写得不错!不过文章中的接口类我着实没搞懂是个啥玩意。。
2 楼 zdsunshine0640 2010-08-22  
学习了,感谢~~~例子还是挺形象的。
1 楼 suifeng 2010-08-22  
列子很形象, 学习了

相关推荐

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    7、门面模式FACADE PATTERN 8、适配器模式ADAPTER PATTERN 9、模板方法模式TEMPLATE METHOD PATTERN 10、建造者模式BUILDER PATTERN 11、桥梁模式BRIDGE PATTERN 12、命令模式COMMAND PATTERN 13、装饰模式...

    设计模式 之 “门面模式[Facade Pattern]”

    NULL 博文链接:https://lym6520.iteye.com/blog/707060

    解析C#设计模式编程中外观模式Facade Pattern的应用

    主要介绍了C#设计模式编程中外观模式Facade Pattern的应用,外观模式中分为门面(Facade)和子系统(subsystem)两个角色来进行实现,需要的朋友可以参考下

    24种设计模式与6大设计原则

    门面模式[FACADE PATTERN] 适配器模式[ADAPTER PATTERN] 模板方法模式[TEMPLATE METHOD PATTERN] 建造者模式[BUILDER PATTERN] 策略模式 代理模式 单例模式 多例模式 工厂方法模式 抽象工厂模式 门面模式 适配器...

    详解PHP中的外观模式facade pattern

    facade这个词,原意指的是一个建筑物的表面、外观,在建筑学中被翻译为“立面”这个术语,国内对facade这个词的关注,可能更多要依赖于laravel的流行,似乎都一致把laravel里的facade翻译作“门面”。说实在的,当第...

    php设计模式 Facade(外观模式)

    模式定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。...

    JAVA设计模式.rar

    门面模式【FACADE PATTERN】  适配器模式【ADAPTER PATTERN】  模板方法模式【TEMPLATE METHOD PATTERN】  建造者模式【BUILDER PATTERN】 桥梁模式【BRIDGE PATTERN】  命令模式【COMMAND PATTERN...

    网络编程、常用设计模式

    一、门面模式(Facade Pattern) 23 二、门面模式的结构 24 三、在什么情况下使用门面模式 24 【五】、适配器模式 25 一、适配器模式(Adapter Pattern) 25 二、类的Adapter模式的结构 25 三、对象的Adapter模式的结构 ...

    软件开发中的23种设计模式

    23种模式(Pattern) 1、创建形模式: 1)、单用型:Singleton 2)、工厂方法型:Factory Method...3)、门面模式:Facade 4)、装饰模式:Decorator 3、行为型模式 1)、策略模式:Strategy 2)、观察者模式:Observer

    24个设计模式与6大设计原则

    第 7 章 门面模式【FACADE PATTERN】 44 第 8 章 适配器模式【ADAPTER PATTERN】 51 第 9 章 模板方法模式【TEMPLATE METHOD PATTERN】 63 第 10 章 建造者模式【BUILDER PATTERN】 82 第 11 章...

    C#设计模式大全

    一、 门面(Facade)模式 二、 门面模式的结构 三、 门面模式的实现 四、 在什么情况下使用门面模式 五、 一个例子 六、 使用门面模式的设计 设计模式(16)-Bridge Pattern 一、 桥梁(Bridge)模式 二、 ...

    C#设计模式.PDF

    一、 门面(Facade)模式 134 二、 门面模式的结构 134 三、 门面模式的实现 135 四、 在什么情况下使用门面模式 135 五、 一个例子 136 六、 使用门面模式的设计 140 设计模式(16)-Bridge Pattern 144 一、 桥梁...

    第14章_外观模式.ppt

    外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为...

    Java设计模式

    第 7 章 门面模式【FACADE PATTERN】 .................................................................................................... 44 第 8 章 适配器模式【ADAPTER PATTERN】 ..........................

    二十三种设计模式【PDF版】

    设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) 就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,你是单位中的一个元素...

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    超级有影响力霸气的Java面试题大全文档

    超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。...

    Medusa:美杜莎(Medusa)是发布书评的网站。 它有两个面板

    Net Core MVC API和/或ASP.Net Net Core MVC和/或Swagger 存储库模式-依赖注入模式-工作单元模式-适配器设计模式-选项模式-门面设计模式-内存缓存-Fluent API-NLog-自动映射器-Bootstap && Bootswatch 有用的网站:...

Global site tag (gtag.js) - Google Analytics