一、外观模式简介
Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。
二、外观模式的结构
三、外观模式的角色与职责
- Facade: 为调用方定义简单的调用接口。
- Clients : 调用者。通过Facade接口调用提供某功能的内部类群。
- Packages: 功能提供者。指提供功能的类群(模块或子系统)。
四、外观模式的具体实现
现在,有一个家庭影院的项目,包括CDplayer、Light、Projector、Stereo、Screen等设备的安装。
各个设备的接口如下:
// An highlighted block
package design.facade.gys.appliances;
public class CDplayer {
private int volume= 0;
public CDplayer() {
super();
}
public void on() {
System.out.println("CDplayer on");
}
public void off() {
System.out.println("CDplayer off");
}
public void start() {
System.out.println("CDplayer plays music");
}
public void stop() {
System.out.println("CDplayer stops music");
}
public void volumeadd() {
if(volume<=20)
volume++;
System.out.println("CD volumeadd: "+volume);
}
public void volumesub() {
if(volume>0)
volume--;
System.out.println("CD volumesub "+volume);
}
}
// An highlighted block
package design.facade.gys.appliances;
public class Light {
public Light() {
super();
// TODO Auto-generated constructor stub
}
public void on() {
System.out.println("Light on");
}
public void off() {
System.out.println("Light off");
}
public void dim() {
System.out.println("Light dim");
}
}
// An highlighted block
package design.facade.gys.appliances;
public class Projector {
public Projector() {
super();
// TODO Auto-generated constructor stub
}
public void on() {
System.out.println("Projector on");
}
public void off() {
System.out.println("Projector off");
}
public void focus() {
System.out.println("Projector focus");
}
public void zoom() {
System.out.println("Projector zoom");
}
}
// An highlighted block
package design.facade.gys.appliances;
public class Screen {
public Screen() {
super();
// TODO Auto-generated constructor stub
}
public void down() {
System.out.println("screen down");
}
public void up() {
System.out.println("screen up");
}
}
// An highlighted block
package design.facade.gys.appliances;
public class Stereo {
private int volume= 0;
public Stereo() {
super();
// TODO Auto-generated constructor stub
}
public void on() {
System.out.println("Stereo on");
}
public void off() {
System.out.println("Stereo off");
}
public void volumeadd() {
if(volume<=20)
volume++;
System.out.println("Stereo volumeadd: "+volume);
}
public void volumesub() {
if(volume>0)
volume--;
System.out.println("Stereo volumesub "+volume);
}
}
现在有五个遥控器需要我们来控制,一不小心就会拿错。接下来我们就用外观模式来简化遥控器的设计。
方案设计
类设计
我们将所有类似接口实现在一个接口中。on()方法中将所有设备的开都实现在里面,在off()中接入所有的设备关,在start()方法中实现投影仪的聚焦、音响的声音、灯光的闪烁。
// An highlighted block
package design.facade.gys.facade;
import design.facade.gys.appliances.*;
public class Controller {
CDplayer cdplayer=new CDplayer();
Light light=new Light();
Projector projector =new Projector();
Screen screen=new Screen();
Stereo stereo=new Stereo();
public void on() {
cdplayer.on();
light.on();
projector.on();
screen.down();
stereo.on();
}
public void off() {
cdplayer.off();
light.off();
projector.off();
screen.up();
stereo.off();
}
public void start() {
light.dim();
stereo.volumeadd();
projector.focus();
}
}
现在遥控器就剩三个按钮了,一下子就能实现功能的集合,简化了功能。让我们看一下遥控器是否好使。
// An highlighted block
package design.facade.gys.facade;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Controller ct=new Controller();
ct.on();
System.out.println("----------");
ct.start();
System.out.println("----------");
ct.off();
}
}
// An highlighted block
CDplayer on
Light on
Projector on
screen down
Stereo on
----------
Light dim
Stereo volumeadd: 1
Projector focus
----------
CDplayer off
Light off
Projector off
screen up
Stereo off
五、外观模式和命令模式的区别
外观模式将具有类似的功能进行聚集。
命令模式将命令封装成对象。
最少知识原则:尽量减少对象之间的交互,不要让太多的类耦合在一起。
遵循最少知识原则:
对象的方法调用范围:
- 该对象本身
- 作为参数传进来的对象
- 此方法创建和实例化的对象
- 对象的组件