【设计模式系列】外观模式(十四)
一、什么是外观模式
外观模式(Facade Pattern)是一种结构型设计模式,其核心目的是为一个复杂的子系统提供一个简化的接口。这种模式通过定义一个外观类来封装子系统内复杂的操作,隐藏系统内部的复杂性,并向客户端提供一个客户端可以访问系统的接口,同时对客户端隐藏内部的细节。
二、外观模式的角色
-
Facade(外观):
- 功能:外观角色是为子系统提供的一个简化接口。它封装了子系统内部的复杂性,同时提供了一组更高层次的操作来实现这些功能。外观角色通常包含指向子系统组件的引用,并在内部将客户端的请求委托给一个或多个子系统组件。它为子系统定义了一个高层接口,使得子系统更容易使用,同时隐藏了系统的细节和复杂性。
- 特点:外观角色通常是一个具体类,它实现了子系统中所有方法的调用逻辑,并且可能包含子系统中对象的实例。
-
Subsystem(子系统):
- 功能:子系统角色实现了子系统的功能,并且可以被外观角色调用。子系统可以包含一个或多个对象,每个对象都包含了特定的功能。这些子系统对象对外观角色的实现细节一无所知,它们只是简单地提供自己的业务逻辑。
- 特点:子系统角色可以是一个接口或抽象类,以及实现这些接口或抽象类的多个具体类。它们独立于外观角色,即使没有外观角色,子系统也可以独立工作。
三、外观模式的典型应用场景
-
复杂的类库:当一个库有很多复杂的类,且这些类的使用需要深入了解库的内部结构时,可以通过一个外观类提供一个简单的接口来简化客户端的使用。
-
系统集成:在多个子系统集成到一个大型系统中时,每个子系统可能都有自己的接口。外观模式可以用来提供一个统一的接口,隐藏子系统间的复杂交互。
-
第三方接口封装:当需要与第三方服务或API交互时,外观模式可以封装这些服务的细节,提供一个更简单、更符合本地应用习惯的接口。
四、外观模式在BeanFactory中的应用
1. 定义Bean接口和实现类
首先,定义一些bean的接口和实现类:
// MessageService.java
public interface MessageService {
void sendMessage(String message);
}
// EmailService.java
import org.springframework.stereotype.Component;
@Component
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending email: " + message);
}
}
// SMSService.java
import org.springframework.stereotype.Component;
@Component
public class SMSService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending SMS: " + message);
}
}
2. 定义BeanFactory外观类
接下来,定义一个BeanFactory
外观类,它封装了对BeanFactory
的访问:
// MessageServiceFacade.java
import org.springframework.beans.factory.BeanFactory;
public class MessageServiceFacade {
private BeanFactory beanFactory;
public MessageServiceFacade(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void sendEmail(String message) {
MessageService emailService = beanFactory.getBean("emailService", MessageService.class);
emailService.sendMessage(message);
}
public void sendSMS(String message) {
MessageService smsService = beanFactory.getBean("smsService", MessageService.class);
smsService.sendMessage(message);
}
}
3. 配置Spring BeanFactory
在Spring的配置文件中,配置EmailService
和SMSService
bean:
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="emailService" class="com.example.EmailService"/>
<bean id="smsService" class="com.example.SMSService"/>
</beans>
4. 客户端代码
最后,客户端代码使用MessageServiceFacade
来发送消息,而不需要直接与BeanFactory
交互:
// Client.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanFactory beanFactory = context;
MessageServiceFacade messageServiceFacade = new MessageServiceFacade(beanFactory);
messageServiceFacade.sendEmail("Hello via Email");
messageServiceFacade.sendSMS("Hello via SMS");
}
}
在这个示例中,MessageServiceFacade
作为一个外观类,简化了对BeanFactory
的访问。客户端代码通过MessageServiceFacade
来发送邮件和短信,而不需要知道具体的MessageService
实现类或BeanFactory
的细节。这样,MessageServiceFacade
隐藏了系统的复杂性,提供了一个简化的接口给客户端使用,符合外观模式的定义。