源码git地址 https://github.com/dlovetco/designMode
提出问题
一个工人控制着一块区域的电路,他的工作是去管理电路上的开关。请用代码实现这一场景。
简单实现
package facade;
public class Facade {
public static void main(String[] args) {
Switch1 switch1 = new Switch1();
Switch2 switch2 = new Switch2();
Switch3 switch3 = new Switch3();
//打开开关
switch1.turnOn();
switch2.turnOn();
switch3.turnOn();
//关闭开关
switch1.turnOff();
switch2.turnOff();
switch3.turnOff();
}
}
/**
* 开关一
*/
class Switch1{
void turnOn(){
System.out.println("打开开关1");
}
void turnOff(){
System.out.println("关闭开关1");
}
}
class Switch2{
void turnOn(){
System.out.println("打开开关2");
}
void turnOff(){
System.out.println("关闭开关2");
}
}
class Switch3{
void turnOn(){
System.out.println("打开开关3");
}
void turnOff(){
System.out.println("关闭开关3");
}
}
上述代码的缺点是 对于客户端来说,在开关数量过多的情况下很容易弄错。此时作为一个工人多希望有一个总电闸来控制电路。这就是我们的外观模式。
外观模式
package facade;
public class Facade {
public static void main(String[] args) {
TotalSwitch totalSwitch = new TotalSwitch();
//打开开关
totalSwitch.turnOn();
//关闭开关
totalSwitch.turnOff();
}
}
/**
* 总电闸
*/
class TotalSwitch {
Switch1 switch1 = new Switch1();
Switch2 switch2 = new Switch2();
Switch3 switch3 = new Switch3();
//打开开关
void turnOn() {
switch1.turnOn();
switch2.turnOn();
switch3.turnOn();
}
//关闭开关
void turnOff() {
switch1.turnOff();
switch2.turnOff();
switch3.turnOff();
}
}
/**
* 开关一
*/
class Switch1 {
void turnOn() {
System.out.println("打开开关1");
}
void turnOff() {
System.out.println("关闭开关1");
}
}
class Switch2 {
void turnOn() {
System.out.println("打开开关2");
}
void turnOff() {
System.out.println("关闭开关2");
}
}
class Switch3 {
void turnOn() {
System.out.println("打开开关3");
}
void turnOff() {
System.out.println("关闭开关3");
}
}
外观模式的好处就是 工人完全没必要跟繁琐的开关相关联,使用一个较高层次的类来跟底层打交道减少工人的出错率。可以说有了外观模式,相当于给调用者提供了一个统一简单的接口。而具体底层怎么复杂的实现跟调用者完全没有关系。这很好体现了我们之前讲的迪米特法则。
plantuml
@startuml
class TotalSwitch{
Switch1 switch1
Switch3 switch2
Switch2 switch3
turnOn()
turnOff()
}
Switch1 <-- TotalSwitch
class Switch1{
turnOn()
turnOff()
}
Switch2 <-- TotalSwitch
class Switch2{
turnOn()
turnOff()
}
Switch3 <-- TotalSwitch
class Switch3{
turnOn()
turnOff()
}
TotalSwitch<--Worker
class Worker{
TotalSwitch totalSwitch
}
@enduml