外观模式
介绍:
- 外观模式,也叫过程模式,外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只跟这个接口发生调用,而无需关心这个子系统的内部细节。
主要角色说明:
- 外观类:为调用端提供统一的接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象
- 调用者:外观接口的调用者
- 子系统:指模块或子系统,处理facade对象指派的任务,他是功能的实际提供者
问题案例:
创建一个家庭播放影院,各组件配合播放电影功能
public class DvDPlayer {
//构造函数私有化
private DvDPlayer(){}
//静态内部类
public static class Singleton{
static final DvDPlayer instance = new DvDPlayer();
}
//返回单例对象
public static DvDPlayer getInstance(){
return Singleton.instance;
}
public void on(){
System.out.println("DVD 打开");
}
public void off(){
System.out.println("DVD 关闭");
}
public void playing(){
System.out.println("DVD 正在播放");
}
public void pause(){
System.out.println("DVD 暂停");
}
}
public class Light {
//构造函数私有化
private Light(){}
//静态内部类
public static class Singleton{
static final Light instance = new Light();
}
//返回单例对象
public static Light getInstance(){
return Singleton.instance;
}
public void on(){
System.out.println("灯光打开");
}
public void off(){
System.out.println("灯光关闭");
}
public void bright(){
System.out.println("灯光调亮");
}
public void dim(){
System.out.println("灯光调黯");
}
}
public class Popcorn {
//构造函数私有化
private Popcorn(){}
//静态内部类
public static class Singleton{
static final Popcorn instance = new Popcorn();
}
//返回单例对象
public static Popcorn getInstance(){
return Singleton.instance;
}
public void on(){
System.out.println("爆米花机 打开");
}
public void off(){
System.out.println("爆米花机 关闭");
}
public void pop(){
System.out.println("爆米花机 爆米花");
}
}
public class Projector {
//构造函数私有化
private Projector(){}
//静态内部类
public static class Singleton{
static final Projector instance = new Projector();
}
//返回单例对象
public static Projector getInstance(){
return Singleton.instance;
}
public void on(){
System.out.println("投影仪 打开");
}
public void off(){
System.out.println("投影仪 关闭");
}
public void focus(){
System.out.println("投影仪 正在投影");
}
}
public class Screen {
//构造函数私有化
private Screen(){}
//静态内部类
public static class Singleton{
static final Screen instance = new Screen();
}
//返回单例对象
public static Screen getInstance(){
return Singleton.instance;
}
public void up(){
System.out.println("屏幕 上升");
}
public void down(){
System.out.println("屏幕 下降");
}
}
public class Stereo {
//构造函数私有化
private Stereo(){}
//静态内部类
public static class Singleton{
static final Stereo instance = new Stereo();
}
//返回单例对象
public static Stereo getInstance(){
return Singleton.instance;
}
public void up(){
System.out.println("立体声 上升");
}
public void on(){
System.out.println("立体声 打开");
}
public void off(){
System.out.println("立体声 关闭");
}
}
/**
* 门面类,统一管理子系统部件
*/
public class HomeTheaterFacade {
private DvDPlayer dvDPlayer;
private Light light;
private Projector projector;
private Popcorn popcorn;
private Screen screen;
private Stereo stereo;
public HomeTheaterFacade() {
this.dvDPlayer = DvDPlayer.getInstance();
this.light = Light.getInstance();
this.projector = Projector.getInstance();
this.popcorn = Popcorn.getInstance();
this.screen = Screen.getInstance();
this.stereo = Stereo.getInstance();
}
public void ready(){
dvDPlayer.on();
light.dim();
popcorn.on();
screen.down();
stereo.on();
projector.on();
}
public void play(){
dvDPlayer.playing();
}
public void pause(){
dvDPlayer.pause();
}
public void end(){
dvDPlayer.off();
light.bright();
projector.off();
screen.up();
stereo.off();
popcorn.off();
}
}
public class Client {
public static void main(String[] args) {
final HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
homeTheaterFacade.ready();
homeTheaterFacade.play();
homeTheaterFacade.end();
}
}
外观模式在MyBatis框架应用源码分析:
外观模式注意事项和细节:
- 外观模式屏蔽了子系统的细节,因此外观模式降低了客户对子系统使用的复杂度
- 外观模式对客户端与子系统的耦合关系,让子系统内部的模块更易维护和扩展
- 通过合理的使用外观模式,可以帮助我们更好的划分访问的层次
- 当系统需要进行分层设计时,可以考虑使用Facade模式
- 在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个facade类,来提供遗留系统的比较清晰简单的接口,让新系统与facade类交互,提高复用性
- 不能过多或者不合理的使用外观模式,使用外观模式好,还是直接调用模块好,要以让系统有层次,利于维护为目的