外观模式:结构型模式之一,提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。
说白了就是你去商场买一杯奶茶,这个奶茶其实有很多种类,每一个种类的原材料和做法都不一样,但是奶茶店不会给你展示原材料和做法给你看,会直接给你一个菜单让你选,而这个菜单就是外观类。你只需要选奶茶就行了,不用去关心内部怎么实现。
外观角色(Facade):提供一个外观接口,对外,它提供一个易于客户端访问的接口,对内,它可以访问子系统中的所有功能。
子系统角色(SubSystem):子系统在整个系统中可以是一个或多个模块,每个模块都有若干类组成,这些类可能相互之间有着比较复杂的关系。
客户端(Client):外观接口调用测试者。
前言:举个栗子,我们家里有很多家居,比如空调、热水器、窗帘、扫地机器人,假设这些家居都是由不同的对象来进行控制的,就会有空调控制对象、热水器控制对象、窗帘控制对象、扫地机器人控制对象。然而,这些我们都可以不需要,我们只需要一个小爱同学音箱,就可以把这些控制都集中再一个控制器上,我们需要开空调,只需要对小爱同学说开空调就可以了。所以之前的其他遥控器我们都可以不用关心了,我们只需要关注小爱同学就够了。这个时候我们就可以使用外观模式。单例需要构造私有化,这里没有体现。
空调(子系统角色 SubSystem)
@AllArgsConstructor
@NoArgsConstructor
@Data
public class AirConditioner {
private static AirConditioner airConditioner = new AirConditioner();
public static AirConditioner getInstance() {
return airConditioner;
}
public void turnOn() {
System.out.println("打开空调");
}
public void turnOff() {
System.out.println("关闭空调");
}
}
热水器(子系统角色 SubSystem)
public class Calorifier {
private static Calorifier calorifier = new Calorifier();
public static Calorifier getInstance() {
return calorifier;
}
public void turnOn() {
System.out.println("打开热水器");
}
public void turnOff() {
System.out.println("关闭热水器");
}
}
窗帘(子系统角色 SubSystem)
public class Curtain {
private static Curtain curtain = new Curtain();
public static Curtain getInstance() {
return curtain;
}
public void turnOn() {
System.out.println("打开窗帘");
}
public void turnOff() {
System.out.println("关闭窗帘");
}
}
扫地机器人(子系统角色 SubSystem)
public class FloorMoppingRobot {
private static FloorMoppingRobot floorMoppingRobot = new FloorMoppingRobot();
public static FloorMoppingRobot getInstance() {
return floorMoppingRobot;
}
public void turnOn() {
System.out.println("打开扫地机器人");
}
public void turnOff() {
System.out.println("关闭扫地机器人");
}
}
小爱同学(外观角色 Facade)
public class XiaoaiClassmate {
// 定义子系统对象
private AirConditioner airConditioner;
private Calorifier calorifier;
private Curtain curtain;
private FloorMoppingRobot floorMoppingRobot;
// 通过构造器根据单例模式获得子系统对象
public XiaoaiClassmate() {
this.airConditioner = AirConditioner.getInstance();
this.calorifier = Calorifier.getInstance();
this.curtain = Curtain.getInstance();
this.floorMoppingRobot = FloorMoppingRobot.getInstance();
}
public void getUp() {
System.out.println("我要起床啦!");
airConditioner.turnOn();
calorifier.turnOn();
curtain.turnOff();
}
public void goToWork() {
System.out.println("我要去上班啦");
airConditioner.turnOff();
calorifier.turnOff();
floorMoppingRobot.turnOn();
}
}
测试类
public class FacadeTest {
public static void main(String[] args) {
XiaoaiClassmate xiaoaiClassmate = new XiaoaiClassmate();
xiaoaiClassmate.getUp();
xiaoaiClassmate.goToWork();
}
}
输出结果
我要起床啦! 打开空调 打开热水器 关闭窗帘 我要去上班啦 关闭空调 关闭热水器 打开扫地机器人优缺点
优点:
使复杂子系统的接口变的简单可用,实现了子系统与客户之间的松耦合关系,减少了客户端对子系统的依赖,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。外观模式也遵循了迪米特法则。
缺点:
在不对外观类进行抽象的时候,如果需要添加新的子系统,就需要对外观类进行修改,违背了
参考博客:https://blog.csdn.net/weixin_51466332/article/details/123373754?spm=1001.2014.3001.5502



