面试题答案
一键面试相同点
- 设计目的:装饰器模式、代理模式和策略模式都遵循“开闭原则”,即对扩展开放,对修改关闭。它们都通过一定方式在不修改原有代码的基础上增加新功能。
- 结构特点:三种模式都涉及到对象的组合,通过组合方式关联不同对象,而非继承。
不同点
- 装饰器模式
- 意图:向一个现有的对象添加新功能,同时又不改变其结构。动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
- 结构:有一个抽象组件类,具体组件类实现该抽象组件,装饰器类也实现抽象组件并持有抽象组件的引用。多个装饰器可以层层嵌套对组件进行装饰。
- 应用场景:比如Java I/O流,
BufferedInputStream
可以装饰FileInputStream
,给文件输入流增加缓冲功能。
- 代理模式
- 意图:为其他对象提供一种代理以控制对这个对象的访问。代理对象起到中介作用,可在访问真实对象前后做一些处理,如权限控制、远程调用等。
- 结构:有抽象主题、真实主题和代理主题。代理主题持有真实主题的引用,并通过调用真实主题的方法实现功能,同时可以在前后添加额外逻辑。
- 应用场景:在远程方法调用中,客户端通过代理对象访问远程服务,代理对象负责处理网络连接等细节。
- 策略模式
- 意图:定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。使得算法可独立于使用它的客户而变化。
- 结构:有一个抽象策略类,具体策略类实现该抽象策略。上下文类持有一个抽象策略的引用,通过组合方式使用不同的具体策略。
- 应用场景:支付方式的选择,如支付宝支付、微信支付等不同支付策略可通过策略模式实现,在上下文类中根据用户选择调用不同支付策略。
在高并发Web应用中结合装饰器模式和线程安全机制
- 动态功能增强
假设核心业务逻辑是处理用户请求的服务类
UserRequestService
。
// 抽象组件
interface RequestService {
void processRequest();
}
// 具体组件
class UserRequestService implements RequestService {
@Override
public void processRequest() {
// 核心业务逻辑,如处理用户请求,查询数据库等
System.out.println("Processing user request...");
}
}
// 装饰器抽象类
abstract class RequestServiceDecorator implements RequestService {
protected RequestService requestService;
public RequestServiceDecorator(RequestService requestService) {
this.requestService = requestService;
}
@Override
public void processRequest() {
requestService.processRequest();
}
}
// 日志记录装饰器
class LoggingDecorator extends RequestServiceDecorator {
public LoggingDecorator(RequestService requestService) {
super(requestService);
}
@Override
public void processRequest() {
System.out.println("Logging start...");
super.processRequest();
System.out.println("Logging end...");
}
}
// 性能监控装饰器
class PerformanceMonitoringDecorator extends RequestServiceDecorator {
public PerformanceMonitoringDecorator(RequestService requestService) {
super(requestService);
}
@Override
public void processRequest() {
long startTime = System.currentTimeMillis();
super.processRequest();
long endTime = System.currentTimeMillis();
System.out.println("Performance monitoring: time taken = " + (endTime - startTime) + "ms");
}
}
- 线程安全机制结合
可以使用
java.util.concurrent.locks.Lock
接口来保证线程安全。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// 线程安全装饰器
class ThreadSafeDecorator extends RequestServiceDecorator {
private static final Lock lock = new ReentrantLock();
public ThreadSafeDecorator(RequestService requestService) {
super(requestService);
}
@Override
public void processRequest() {
lock.lock();
try {
super.processRequest();
} finally {
lock.unlock();
}
}
}
- 使用示例
public class Main {
public static void main(String[] args) {
RequestService userService = new UserRequestService();
userService = new ThreadSafeDecorator(userService);
userService = new LoggingDecorator(userService);
userService = new PerformanceMonitoringDecorator(userService);
// 模拟高并发调用
for (int i = 0; i < 10; i++) {
new Thread(() -> userService.processRequest()).start();
}
}
}
通过上述方式,在高并发Web应用中,利用装饰器模式动态地给核心业务逻辑添加功能,如日志记录、性能监控等,同时通过线程安全装饰器(使用 Lock
机制)保证在高并发环境下系统的性能和稳定性。