设计模式 - 门面模式
一、引入
想象一下你去一家餐厅吃饭,你坐在餐桌前,点了一份菜单上的菜品。然后,你并不需要知道厨房里是如何做这些菜的,也不需要去了解每道菜的具体做法和配料。你只需要通过服务员来点菜就可以了。
在这个例子中,你可以将服务员看作是一个门面,他负责和厨房交流,将你的点单传达给厨师,然后把做好的菜端给你。你只需要和服务员打交道,而不需要直接和厨房的工作人员联系。
同样地,门面模式在编程中也是类似的。它提供了一个简单的接口,让你可以直接使用,而不需要了解背后的复杂实现。这样可以让程序设计更加简单和清晰,同时也降低了各个组件之间的耦合度。
二、概念
门面模式(Facade Pattern)是一种结构型设计模式,它提供了一个简化接口,隐藏了系统内部的复杂性,使得外部客户端可以更容易地使用系统。
门面模式的核心思想是将系统的多个子系统进行封装,提供一个统一的接口给客户端使用。这样客户端只需要与门面接口交互,而不需要直接与系统的各个子系统打交道。
三、基本结构
- Facade(门面):它是门面模式的核心类,负责提供一个简单的接口给客户端,它内部会调用系统中各个子系统的功能来完成客户端的请求。
- Subsystem(子系统):它是系统中的各个模块或组件,负责处理具体的业务逻辑。
四、示例代码
假设我们有一个消息发送系统,它包括了发送短信、电子邮件等功能。我们可以通过门面模式来封装这些复杂的操作,提供一个简单的接口供客户端使用。
/**
* 发送电子邮件接口
*/
public interface EamilSmsService {
void sendEmail();
}
/**
* 发送电子邮件具体实现方法
*/
public class EamilSmsServiceImpl implements EamilSmsService {
@Override
public void sendEmail() {
System.out.println("发送邮件");
}
}
/**
* 发送短信接口
*/
public interface AliSmsService {
void sendSms();
}
/**
* 发送短信具体实现方法
*/
public class AliSmsServiceImpl implements AliSmsService {
@Override
public void sendSms() {
System.out.println("发送阿里短信");
}
}
/**
* 门面统一
*/
public class Computer {
AliSmsService aliSmsService;
EamilSmsService eamilSmsService;
public Computer() {
aliSmsService = new AliSmsServiceImpl();
eamilSmsService = new EamilSmsServiceImpl();
}
public void sendMsg() {
aliSmsService.sendSms();
eamilSmsService.sendEmail();
}
}
客户端
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
computer.sendMsg();
}
}
五、用途
- API库:许多软件提供了API库,将复杂的功能封装在简单的接口中,使得开发者可以轻松地使用这些功能,而不需要了解内部的实现细节。
- 数据库连接池:数据库连接池提供了一个统一的接口,让开发者可以从池中获取数据库连接,而不需要了解数据库连接的创建和管理过程。
- Spring框架:Spring框架提供了许多模块,比如Spring MVC、Spring Boot等,它们为开发者提供了简单的接口,隐藏了底层的复杂性。
六、总结
- 简化接口:通过门面类,客户端可以直接调用一个简单的接口,而无需了解系统内部的复杂性。
- 降低耦合度:客户端只需要与门面类进行交互,而不需要知道系统的具体实现细节,从而降低了系统的耦合度。
- 提高安全性:通过门面类可以控制客户端对系统的访问权限,从而提高了系统的安全性。
- 更好地划分层次:可以将系统划分为多个层次,每个层次都有一个对外的门面类,从而更好地管理和维护系统。
门面模式的缺点:
- 可能导致性能问题:如果门面类的接口设计不合理,可能会导致性能问题,因为它需要调用多个子系统来完成一个请求。
- 可能增加系统复杂性:如果门面类的设计不当,可能会导致门面类本身也变得复杂,从而增加了系统的复杂性。