原创文章,如有转载,请注明出处:http://blog.csdn.net/myth13141314/article/details/78334695
在日常开发过程中时常需要用到设计模式,但是设计模式有23种,如何将这些设计模式了然于胸并且能在实际开发过程中应用得得心应手呢?和我一起跟着《Android源码设计模式解析与实战》一书边学边应用吧!
设计模式系列文章
- Android 设计模式之面向对象的六大原则
- Android 设计模式之Builder模式
- Android 设计模式之观察者模式
- Android 设计模式之单例模式
- Android 设计模式之代理模式
- Android设计模式之装饰模式
- Android 设计模式之原型模式
- Android 设计模式之工厂方法模式
- Android 设计模式之策略模式
- Android 设计模式之适配器模式
- Android 设计模式之桥接模式
- Android 设计模式之状态模式
今天我们要讲的是外观模式(门面模式,Facade模式)
定义
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个统一的高层次的接口,使得子系统更容易使用
使用场景
- 为一个复杂的子系统提供一个简单接口,对外隐藏子系统的具体实现、隔离变化
- 当需要构建一个层次结构的子系统时,使用外观模式定义子系统中每层的入口点。如果子系统间是相互依赖的,你可以让它们仅通过Facade接口进行通信,从而简化它们之间的依赖关系
使用例子
- 很多的第三方SDK,比如友盟统计
- 我们平时开发过程中封装的模块,比如网络模块、ImageLoader模块等
实现
2大角色
- 外观接口或者类
- 其他的内部子系统
实现的要点
- 主要是把所有需要对外暴露的方法都统一在外观接口或类里面,隐藏其他的子模块
实现方式
先通过一个简单的例子来了解外观模式。我们的手机可以看作是一个外观类,而手机中的功能,比如打电话、相机则是各种子模块。
- 打电话的功能
//电话功能接口
public interface Phone {
//打电话
public void dail();
//挂断
public void hangup();
}
//电话的实现类
public class PhoneImpl implements Phone {
@Override
public void dail() {
System.out.println("打电话");
}
@Override
public void hangup() {
System.out.println("挂断");
}
}
- 相机的功能
//相机功能接口
public interface Camera {
//打开相机
public void open();
//拍照
public void takePhoto();
//关闭相机
public void close();
}
//相机功能的实现类
public class MiCamera implements Camera {
@Override
public void open() {
System.out.println("打开相机");
}
@Override
public void takePhoto() {
System.out.println("拍照");
}
@Override
public void close() {
System.out.println("关闭相机");
}
}
- 手机
public class MobilePhone {
private Phone mPhone = new PhoneImpl();
private Camera mCamera = new MiCamera();
//拍照
public void takePhoto() {
mCamera.open();
mCamera.takePhoto();
mCamera.close();
}
//视频聊天
public void videoChat() {
mCamera.open();
mPhone.dail();
}
}
- 我们使用手机时,需要用到拍照和视频聊天的功能,但我们不需要知道相机的信息,也不需要知道视频聊天要用到了哪些类,Phone的接口和实现等,只需要用到手机MobilePhone这个类和它提供的接口takePhoto和videoChat
MobilePhone mobilePhone = new MobilePhone();
mobilePhone.takePhoto();
mobilePhone.videoChat();
下面我们再通过我们的ImageLoader来看看外观模式的运用
- 外观类ImageLoader,所有的功能都通过调用ImageLoader类来实现
public class ImageLoader {
//图片加载配置
ImageLoaderConfig mConfig;
// 图片缓存,依赖接口
ImageCache mImageCache = new MemoryCache();
//请求队列
private RequestQueue requestQueue;
private static ImageLoader mImageLoader = null;
private ImageLoader () {}
public static ImageLoader getInstance() {
//省略单例实现
}
public void init(ImageLoaderConfig config) {
mConfig = config;
mImageCache = config.mImageCache;
checkConfig();
requestQueue = new RequestQueue(config.threadCount);
requestQueue.start();
}
private void checkConfig() {
//省略部分代码
}
public ImageLoaderConfig getConfig() {
return mConfig;
}
public void displayImage(final ImageView imageView, String url) {
displayImage(imageView, url, null);
}
public void displayImage(final ImageView imageView, String url, DisplayConfig config) {
ImageRequest request = new ImageRequest(imageView, url, config);
request.displayConfig = request.displayConfig != null ? request.displayConfig : mConfig.displayConfig;
requestQueue.addRequest(request);
}
}
- ImageLoader类里面封装了配置类ImageLoaderConfig和请求队列RequestQueue。请求队列RequestQueue里面又封装了线程模型等
- 调用ImageLoader的init方法以后,用户就可以直接用display方法来加载显示图片了,而不用管网络请求、队列这些细节
- 所有的实现细节都被封装在ImageLoader类下面,用户只需要操作ImageLoader的接口就可以完成图片的加载操作,这样就避免暴露了过多的实现细节,而且用户使用起来也更加简单
总结
- 外观模式是一个高频率使用的设计模式,关键就在于封装
- 外观模式对外隐藏了子系统的实现细节,减少了客户端对子系统的耦合,能拥抱变化
- 外观类对子系统的接口封装,使得系统更易于使用
欢迎关注我的公众号,和我一起每天进步一点点!