一、外观模式
提供一个统一的接口,来访问子系统中一群功能相关接口外观模式定义了一个高层接口,让子系统更容易使用
二、示例
组件一个家庭影院:家里有DVD播放器、投影仪、自动屏幕、环绕立体声、爆米花机
当想看的话需要进行多项操作:
- 开爆米花机
- 放下屏幕
- 开投影仪
- 开音响
- 开DVD,选dvd 去拿爆米花
- 调暗灯光
- 播放
- 观影结束后,关闭各种设备
对于用户来说无需知道每个对象的开关,只需要一个总程序的开关即可。
则需要使用外观模式定义一个总遥控器,只对外开放出用户关心的功能。
/**
* DVD播放器
*/
public class DVDPlayer {
private static DVDPlayer instance = null;
private DVDPlayer() {
}
public static DVDPlayer getInstance() {
if (instance == null) {
instance = new DVDPlayer();
}
return instance;
}
public void on() {
System.out.println("DVDPlayer On");
}
public void off() {
System.out.println("DVDPlayer Off");
}
public void play() {
System.out.println("DVDPlayer is playing");
}
public void pause() {
System.out.println("DVDPlayer pause");
}
public void setdvd() {
System.out.println("DVDPlayer is setting dvd");
}
}
/**
* 爆米花机
*/
public class Popcorn {
private static Popcorn instance = null;
private Popcorn() {
}
public static Popcorn getInstance() {
if (instance == null) {
instance = new Popcorn();
}
return instance;
}
public void on() {
System.out.println("Popcorn On");
}
public void off() {
System.out.println("Popcorn Off");
}
public void pop() {
System.out.println("Popcorn is popping");
}
}
/**
* 升降屏幕
*/
public class Screen {
private static Screen instance = null;
private Screen() {
}
public static Screen getInstance() {
if (instance == null) {
instance = new Screen();
}
return instance;
}
public void up() {
System.out.println("Screen up");
}
public void down() {
System.out.println("Screen down");
}
}
/**
* 外观模式,统一封装提供给外部使用的接口程序
*/
public class HomeTheaterFacade {
private TheaterLights mTheaterLights;
private Popcorn mPopcorn;
private Stereo mStereo;
private Projector mProjector;
private Screen mScreen;
private DVDPlayer mDVDPlayer;
public HomeTheaterFacade() {
mTheaterLights = TheaterLights.getInstance();
mPopcorn = Popcorn.getInstance();
mStereo = Stereo.getInstance();
mProjector = Projector.getInstance();
mScreen = Screen.getInstance();
mDVDPlayer = DVDPlayer.getInstance();
}
/**
* 组合多项功能,给外部透出一个总控制的方法
*/
public void ready() {
mPopcorn.on();
mPopcorn.pop();
mScreen.down();
mProjector.on();
mStereo.on();
mDVDPlayer.on();
mDVDPlayer.setdvd();
mTheaterLights.dim(10);
}
public void end() {
mPopcorn.off();
mTheaterLights.bright();
mScreen.up();
mProjector.off();
mStereo.off();
mDVDPlayer.setdvd();
mDVDPlayer.off();
}
public void play() {
mDVDPlayer.play();
}
public void pause() {
mDVDPlayer.pause();
}
}
/**
* 外观模式,封装统一的接口,提供给外部访问
*/
public class MainTest {
public static void main(String[] args) {
HomeTheaterFacade mHomeTheaterFacade=new HomeTheaterFacade();
// 用户只调用需要的总开关即可
mHomeTheaterFacade.ready();
mHomeTheaterFacade.play();
}
}
三、最少知识原则
最少知识原则:尽量减少对象之间的交互,只留几个“密友” 项目设计中就是不要让太多的类耦合在一起
对象的方法调用范围:
- 该对象本身
- 作为参数传进来的对象
- 此方法创建和实例化的对象
- 对象的组件
四、总结
1.与命令模式的区别
之前文章中讲述的命令模式也有过多项组合命令的例子,但是与乐观模式不同的是命令模式的侧重点在于将操作封装成命令,利用统一的命令进行操作。
2.特点
松散耦合,使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护
简单易用,客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。
更好的划分访问层次,有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。
Java设计模式所有示例代码,持续更新中