一、概述
一般问题:子系统功能过度分散,对外提供接口太多,导致外部调用繁琐
核心方案:子系统的外部与其内部通信必须通过一个统一的门面(Facade)对象进行。外观模式提供一个高层次的接口,使得子系统更易于使用。
设计意图:为了降低用户访问复杂内部子系统的复杂度,把子系统过度拆分的分散功能,组合成一个整体,对外提供一个统一的接口。外观模式设计意图非常直白,没有一般化的类图描述,下面是一个示意性对象图
子系统并不知道门面对象的存在,门面对象实际上也是一个子系统的Client。
外观模式的主要目的有两个:
- 省心——外部调用者与子系统的对接由多个功能入口简化为一个统一门面入口
- 独立——子系统更加独立,直接服务对象由多个Client简化成一个Facade
二、实例讲解
在日常开发中,我们实际上总是有意无意地使用外观模式。比如,在开发一个新模块时,我们总是希望它保持独立性,减少与现有系统的耦合。于是经常会建立一个xxxManager类,负责整个子模块的对外接口。这实际上就是外观模式的核心思路。
我曾经需要在锁屏模块开发一个画廊模块,主要负责预下载一些漂亮壁纸供用户浏览。这是一个相对独立的子模块,内部涉及网络、数据库、浏览逻辑等功能。我不希望这些功能入口直接被外部调用,这样会增加以后维护成本。于是,我在开发完这些功能之后,创建了一个GalleryWallpaperManager类,负责整个画廊模块功能对外接口。
所有外部Client通过GalleryWallpaperManager调用gallery model内部功能。
示例代码:
/** * gallery核心控制类 * * @author kevin * */ public class GalleryWallpaperManager { /* 启动下载*/ public void start() { if (isCta()) { Log.i(TAG, "gallery load returned for cta!"); return; } Log.i(TAG, "gallery load start"); if (isBind) { mGalleryLoader.start(); } else { Intent intent = new Intent(mContext, GalleryLoader.class); mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } } /*获取壁纸列表*/ public List<GalleryItem> getGalleryItemList() { return mDbHelper.getGalleryItemList(); } }
三、总结
总结:外观模式又称门面模式,是一种结构型设计模式,可以为调用者带来极大的方便,设计意图简单直白,日常使用较多。用一句话表述外观模式:
回家爱怎么吵怎么吵,在外面以我说了算
优点:
- 减少系统耦合
- 提高了子系统独立性
- 方便子系统内部状态控制
缺点:
增加了调用层级