写在后面
- 记录学习设计模式的笔记
- 进步对设计模式的灵活运用
学习地址
https://www.bilibili.com/video/BV1G4411c7N4
https://www.bilibili.com/video/BV1Np4y1z7BU
参考文章
http://c.biancheng.net/view/1317.html
我的项目源码
https://gitee.com/zhuang-kang/DesignPattern
13,外观模式
13.1 外观模式的定义和特点
外观(Facade)模式又叫作门面模式, 是一种通过为多个简单的子系统提供一个统一的接口,而使这些子系统更加容易被拜访的模式。 该模式对外有一个对立接口,内部应用程序不必关怀外部子系统的具体细节,这样会大大降低应用程序的复杂度,进步了程序的可维护性。
外观(Facade)模式是“迪米特法令”的典型利用, 它有以下次要长处。
- 升高了子系统与客户端之间的耦合度,使得子系统的变动不会影响调用它的客户类。
- 对客户屏蔽了子系统组件,缩小了客户解决的对象数目,并使得子系统应用起来更加容易。
- 升高了大型软件系统中的编译依赖性,简化了零碎在不同平台之间的移植过程,因为编译一个子系统不会影响其余的子系统,也不会影响外观对象。
外观(Facade)模式的次要毛病如下。
- 不能很好地限度客户应用子系统类,很容易带来未知危险。
- 减少新的子系统可能须要批改外观类或客户端的源代码,违反了“开闭准则”。
13.2 外观模式的构造与实现
13.2.1 外观模式的构造
外观(Facade)模式蕴含以下次要角色。
- 外观(Facade)角色:为多个子系统对外提供一个独特的接口。
- 子系统(Sub System)角色:实现零碎的局部性能,客户能够通过外观角色拜访它。
- 客户(Client)角色:通过一个外观角色拜访各个子系统的性能。
13.2.2 代码实现
关系类图
AirCondition
package com.zhuang.facade;
/**
* @Classname AirCondition
* @Description 空调类
* @Date 2021/3/24 19:23
* @Created by dell
*/
public class AirCondition {public void on() {System.out.println("空调关上...");
}
public void off() {System.out.println("空调敞开...");
}
}
Light
package com.zhuang.facade;
/**
* @Classname Light
* @Description 电灯类
* @Date 2021/3/24 19:23
* @Created by dell
*/
public class Light {public void on() {System.out.println("电灯关上...");
}
public void off() {System.out.println("电灯敞开...");
}
}
TV
package com.zhuang.facade;
/**
* @Classname TV
* @Description 电视类
* @Date 2021/3/24 19:23
* @Created by dell
*/
public class TV {public void on() {System.out.println("电视关上...");
}
public void off() {System.out.println("电视敞开...");
}
}
SmartAppliancesFacade
package com.zhuang.facade;
/**
* @Classname SmartAppliancesFacade
* @Description 智能音箱类 外观类
* @Date 2021/3/24 19:24
* @Created by dell
*/
public class SmartAppliancesFacade {
private Light light;
private TV tv;
private AirCondition airCondition;
public SmartAppliancesFacade() {light = new Light();
tv = new TV();
airCondition = new AirCondition();}
// 公有关上办法 外界拜访不了
// 一键关上
private void on() {light.on();
tv.on();
airCondition.on();}
// 公有敞开办法 外界拜访不了
// 一键敞开
private void off() {light.off();
tv.off();
airCondition.off();}
// 判断办法
public void say(String message) {if (message.contains("关上")) {on();
} else if (message.contains("敞开")) {off();
} else {System.out.println("你说的指令我听不懂!!!");
}
}
}
Client
package com.zhuang.facade;
/**
* @Classname Client
* @Description 外观模式测试类
* @Date 2021/3/24 19:24
* @Created by dell
*/
public class Client {public static void main(String[] args) {SmartAppliancesFacade smartAppliancesFacade = new SmartAppliancesFacade();
smartAppliancesFacade.say("关上家电");
System.out.println("=================");
smartAppliancesFacade.say("敞开家电");
}
}
13.3 外观模式的利用场景
- 对分层构造零碎构建时,应用外观模式定义子系统中每层的入口点能够简化子系统之间的依赖关系。
- 当一个简单零碎的子系统很多时,外观模式能够为零碎设计一个简略的接口供外界拜访。
- 当客户端与多个子系统之间存在很大的分割时,引入外观模式可将它们拆散,从而进步子系统的独立性和可移植性。
13.4 源码解析
应用 tomcat 作为 web 容器时,接管浏览器发送过去的申请,tomcat 会将申请信息封装成 ServletRequest 对象,如下图①处对象。然而大家想想 ServletRequest 是一个接口,它还有一个子接口 HttpServletRequest,而咱们晓得该 request 对象必定是一个 HttpServletRequest 对象的子实现类对象,到底是哪个类的对象呢?能够通过输入 request 对象,咱们就会发现是一个名为 RequestFacade 的类的对象。
RequestFacade 类就应用了外观模式
为什么在此处应用外观模式呢?
定义 RequestFacade 类,别离实现 ServletRequest,同时定义公有成员变量 Request,并且办法的实现调用 Request 的实现。而后,将 RequestFacade 上转为 ServletRequest 传给 servlet 的 service 办法,这样即便在 servlet 中被下转为 RequestFacade,也不能拜访公有成员变量对象中的办法。既用了 Request,又能避免其中办法被不合理的拜访。
写在最初
- 如果我的文章对你有用,请给我点个👍,感激你😊!
- 有问题,欢送在评论区指出!💪