前言
外观模式的目的是隐藏复杂的内部逻辑,让客户端只需要调对外的统一接口,隐藏了系统的复杂性,这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。
使用场景
1、当你要为一个复杂子系统提供一个简单接口时。
2、客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
3、当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
UML角色
Facade:系统对外统一接口,控制系统内部的工作。
SystemA、SystemB:子系统对象,管好自己在某个功能模块应该干的事,提供子系统接口。
Demo
这个设计模式很简单,而且或多或少在工作中也会使用到,我们简单抽象一个计算机的模型,简单的实现几个功能:开机、关机、拍摄照片。我们先以子系统入手:CPU、Camera、HardDisk,Memory…
我们简单的完成三个功能:开机、拍照、关机。那么各个子系统有子系统对外的接口:
CPU:
package com.demo.facade;
import android.util.Log;
/**
* Created by italkbb on 2018/1/19.
*/
public class CPU {
public void start(){
Log.e("zkh","Cpu开始工作");
}
public void startTask(){
Log.e("zkh","CPU调度开始");
}
public void endTask(){
Log.e("zkh","CPU调度结束");
}
public void shutdown(){
Log.e("zkh","Cpu停止工作");
}
}
HardDisk:
package com.demo.facade;
import android.util.Log;
/**
* Created by italkbb on 2018/1/19.
*/
public class HardDisk {
public void start(){
Log.e("zkh","硬盘开始工作");
}
public void writeFile(){
Log.e("zkh","文件写入硬盘");
}
public void readFile(){
Log.e("zkh","硬盘读取文件");
}
public void shutdown(){
Log.e("zkh","硬盘停止工作");
}
}
Memory:
package com.demo.facade;
import android.util.Log;
/**
* Created by italkbb on 2018/1/19.
*/
public class Memory {
public void giveTaskRAM(){
Log.e("zkh","分配内存");
}
public void clearTaskRAM(){
Log.e("zkh","释放内存");
}
}
Camera:
package com.demo.facade;
import android.util.Log;
/**
* Created by italkbb on 2018/1/19.
*/
public class Camera {
public void startCamera(){
Log.e("zkh","打开相机");
}
public void endCamera(){
Log.e("zkh","释放相机");
}
public void giveCameraDate(){
Log.e("zkh","打开相机获取数据并写入内存");
}
}
各自子系统都各司其职的完成自己的工作,那么我们的Facade对象负责封装这些方法,再对外公布接口:
Computer:
package com.demo.facade;
/**
* Created by italkbb on 2018/1/19.
*/
public class Computer {
private CPU cpu;
private HardDisk hardDisk;
private Memory memory;
private Camera camera;
public Computer(){
cpu = new CPU();
hardDisk = new HardDisk();
memory = new Memory();
camera = new Camera();
}
/**
* 开机
*/
public void startComputer(){
cpu.start();
hardDisk.start();
}
/**
* 关机
*/
public void shutdownComputer(){
hardDisk.shutdown();
cpu.shutdown();
}
/**
* 拍照
*/
public void takePicture(){
cpu.startTask();
memory.giveTaskRAM();
camera.startCamera();
camera.giveCameraDate();
hardDisk.writeFile();
memory.clearTaskRAM();
camera.endCamera();
}
}
那么三个功能基本就完成了,对于Client端只需要简单的调用Computer的方法就完成了开关机以及拍照。
后记
外观模式使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护,而且外部调用根本不需要了解内部的结构,只需要跟Facade交互就可以,逻辑很清晰;对于缺点增加新的子系统可能需要修改外观类或客户端,违背了“开闭原则”。