Java常用设计模式(七)---外观模式
本文主要介绍了Java23种设计模式中的外观模式,并结合实例描述了 模式的具体实现和性能分析测试。
1. 简介
它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。
外观模式结构:
SubSystem: 子系统角色。表示一个系统的子系统或模块。
Facade: 外观角色,客户端通过操作外观角色从而达到控制子系统角色的目的。对于客户端来说,外观角色好比一道屏障,对客户端屏蔽了子系统的具体实现。
2. 具体实现
/**
* 子系统角色类
* 电脑CPU
*
* @author illusoryCloud
*/
public class CPU {
public void startUp(){
System.out.println("cpu is startUp...");
}
public void shutDown(){
System.out.println("cpu is shutDown...");
}
}
/**
* 子系统角色类
* 电脑硬盘
*
* @author illusoryCloud
*/
public class Disk {
public void startUp() {
System.out.println("disk is startUp...");
}
public void shutDown() {
System.out.println("disk is shutDown...");
}
}
/**
* 子系统角色类
* 电脑内存
*
* @author illusoryCloud
*/
public class Memory {
public void startUp() {
System.out.println("memory is startUp...");
}
public void shutDown() {
System.out.println("memory is shutDown...");
}
}
/**
* 外观角色
* 电脑
* 用户通过操作当前类即可达到操作所有子系统的目的
*
* @author illusoryCloud
*/
public class Computer {
private CPU cpu;
private Disk disk;
private Memory memory;
public Computer() {
cpu = new CPU();
disk = new Disk();
memory = new Memory();
}
public void startUp() {
cpu.startUp();
disk.startUp();
memory.startUp();
}
public void shutDown() {
cpu.shutDown();
disk.shutDown();
memory.shutDown();
}
}
/**
* 外观模式 测试类
*
* @author illusoryCloud
*/
public class FacedeTest {
@Test
public void facedeTest() {
Computer computer = new Computer();
computer.startUp();
System.out.println("------------------");
computer.shutDown();
}
}
3. 总结
外观模式的优点
外观模式有如下几个优点:
1、松散耦合
外观模式松散了客户端和子系统的耦合关系,让子系统内部的模块能更容易扩展和维护
2、简单易用
客户端不需要了解系统内部的实现,也不需要和众多子系统内部的模块交互,只需要和外观类交互就可以了
3、更好地划分层次
通过合理使用Facade,可以帮助我们更好地划分层次。有些方法是系统对内的,有些方法是对外的,把需要暴露给外部的功能集中到Facade中,这样既方便客户端使用,也很好地隐藏了内部的细节
4. Tomcat中的外观模式
Tomcat中有很多场景都使用到了外观模式,因为Tomcat中有很多不同的组件,每个组件需要相互通信,但又不能将自己内部数据过多地暴露给其他组件。用外观模式隔离数据是个很好的方法,比如Request上使用外观模式。
比如Servlet,doGet和doPost方法,参数类型是接口HttpServletRequest和接口HttpServletResponse,那么Tomcat中传递过来的真实类型到底是什么呢?
在真正调用Servlet前,会经过很多Tomcat方法,传递给Tomcat的request和response的真正类型是一个Facade类。
Request类
public HttpServletRequest getRequest() {
if (facade == null) {
facade = new RequestFacade(this);
}
return facade;
}
Response类
public HttpServletResponse getResponse() {
if (facade == null) {
facade = new ResponseFacade(this);
}
return (facade);
}
因为Request类中很多方法都是组件内部之间交互用的,比如setComet、setReuqestedSessionId等方法,这些方法并不对外公开,但又必须设置为public,因为还要和内部组件交互使用。最好的解决方法就是通过使用一个Facade类,屏蔽掉内部组件之间交互的方法,只提供外部程序要使用的方法。
如果不使用Facade,直接传递的是HttpServletRequest和HttpServletResponse,那么熟悉容器内部运作的开发者可以分别把ServletRequest和ServletResponse向下转型为HttpServletRequest和HttpServletResponse,这样就有安全性的问题了。
5. 参考
https://www.cnblogs.com/xrq730/p/4908822.html