外观模式
适用于:
一个系统有很多类,且外界要与全部或大部分的这些类进行交互。原理:
提供一个统一的对外接口,外界对象要访问这个系统中的一堆接口时,只需调用这个统一的对外接口即可。
作用:
1、把功能汇聚。
2、解耦。原来外面的对象要接触里面的类,现在只要接触这个系统统一的对外接口即可。
家庭影院。
一个遥控器可以实现把所有设备都打开、关闭、暂停等等的功能。
有N多个类:
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 Projector {
private int size=5;
private static Projector instance = null;
private Projector() {
}
public static Projector getInstance() {
if (instance == null) {
instance = new Projector();
}
return instance;
}
public void on() {
System.out.println("Projector On");
}
public void off() {
System.out.println("Projector Off");
}
public void focus() {
System.out.println("Popcorn is focus");
}
public void zoom(int size) {
this.size=size;
System.out.println("Popcorn zoom to"+size);
}
}
音响:
public class Stereo {
private static Stereo instance = null;
private int volume = 5;
private Stereo() {
}
public static Stereo getInstance() {
if (instance == null) {
instance = new Stereo();
}
return instance;
}
public void on() {
System.out.println("Stereo On");
}
public void off() {
System.out.println("Stereo Off");
}
public void setVolume(int vol) {
volume = vol;
System.out.println("the volume of Stereo is set to " + volume);
}
public void addVolume() {
if (volume < 11) {
volume++;
setVolume(volume);
}
}
public void subVolume() {
if (volume > 0) {
volume--;
setVolume(volume);
}
}
}
灯光:
public class TheaterLights {
private static TheaterLights instance = null;
private TheaterLights() {
}
public static TheaterLights getInstance() {
if (instance == null) {
instance = new TheaterLights();
}
return instance;
}
public void on() {
System.out.println("TheaterLights On");
}
public void off() {
System.out.println("TheaterLights Off");
}
public void dim(int d) {
System.out.println("TheaterLights dim to " + d + "%");
}
public void bright() {
dim(100);
System.out.println("TheaterLights bright");
}
}
上面这些类都有对应的物理实体,故可以用单例模式来定义。这些类的操作都差不多,我们只需写一个类似遥控器的类来统一操作即可:
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();
}
}
这样,大大简化了外界调用的操作。现在写个类(Test.java)来测试一下:
public class Test {
public static void main(String[] args) {
HomeTheaterFacade mHomeTheaterFacade=new HomeTheaterFacade();
mHomeTheaterFacade.ready();
mHomeTheaterFacade.play();
}
}
运行结果:
Popcorn On
Popcorn is popping
Screen down
Projector On
Stereo On
DVDPlayer On
DVDPlayer is setting dvd
TheaterLights dim to 10%
DVDPlayer is playing
哈哈,正常运行出来了。
至此,例子就完全做完了。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面是一些笔记:
与命令模式的区别:
外观模式侧重子系统对外暴露接口,简化调用操作。
最少知识原则:
尽量减少类之间的耦合。交互的类和接口越少越好。
外观模式是最少知识原则的一个体现和使用。
对象的方法可以调用:
该对象本身
作为参数传进来的对象
此方法创建和实例化的对象
对象的组件
方法的返回值对象不可以被调用,它违反了最少知识原则。