Organized 50 interview questions into 12 categories: - 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc. - 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理 - 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc. - 04-消息队列 (1 file): RocketMQ/Kafka - 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc. - 06-JVM (1 file): JVM和垃圾回收 - 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc. - 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮 - 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化 - 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx - 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性 - 12-面试技巧 (1 file): 面试技巧和职业规划 All files renamed to Chinese for better accessibility and organized into categorized folders for easier navigation. Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
1048 lines
21 KiB
Markdown
1048 lines
21 KiB
Markdown
# 设计模式
|
||
|
||
## 问题
|
||
|
||
1. 什么是设计模式?设计模式的六大原则是什么?
|
||
2. 单例模式的实现方式有哪些?如何保证线程安全?
|
||
3. 工厂模式和抽象工厂模式的区别是什么?
|
||
4. 观察者模式的应用场景有哪些?Spring 中哪些地方用到了观察者模式?
|
||
5. 策略模式如何解决 if-else 过多的问题?
|
||
6. 装饰器模式和代理模式的区别是什么?
|
||
7. 在实际项目中如何使用设计模式?
|
||
|
||
---
|
||
|
||
## 标准答案
|
||
|
||
### 1. 设计模式的六大原则(SOLID + 1)
|
||
|
||
#### **单一职责原则(Single Responsibility Principle)**
|
||
|
||
**定义**:一个类只负责一个职责。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 违反单一职责
|
||
class UserService {
|
||
public void saveUser(User user) { }
|
||
public void sendEmail(User user) { }
|
||
public void log(User user) { }
|
||
}
|
||
|
||
// ✅ 符合单一职责
|
||
class UserService {
|
||
public void saveUser(User user) { }
|
||
}
|
||
|
||
class EmailService {
|
||
public void sendEmail(User user) { }
|
||
}
|
||
|
||
class LogService {
|
||
public void log(User user) { }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **开闭原则(Open-Closed Principle)**
|
||
|
||
**定义**:对扩展开放,对修改关闭。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 每次新增类型需要修改代码
|
||
class OrderService {
|
||
public double calculateDiscount(String type, double price) {
|
||
if (type.equals("VIP")) {
|
||
return price * 0.8;
|
||
} else if (type.equals("SVIP")) {
|
||
return price * 0.7;
|
||
}
|
||
// 新增类型需要修改这里
|
||
return price;
|
||
}
|
||
}
|
||
|
||
// ✅ 使用策略模式
|
||
interface DiscountStrategy {
|
||
double calculate(double price);
|
||
}
|
||
|
||
class VipDiscount implements DiscountStrategy {
|
||
@Override
|
||
public double calculate(double price) {
|
||
return price * 0.8;
|
||
}
|
||
}
|
||
|
||
class OrderService {
|
||
private Map<String, DiscountStrategy> strategyMap = new HashMap<>();
|
||
|
||
public void registerStrategy(String type, DiscountStrategy strategy) {
|
||
strategyMap.put(type, strategy);
|
||
}
|
||
|
||
public double calculateDiscount(String type, double price) {
|
||
DiscountStrategy strategy = strategyMap.get(type);
|
||
return strategy != null ? strategy.calculate(price) : price;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **里氏替换原则(Liskov Substitution Principle)**
|
||
|
||
**定义**:子类可以替换父类出现在父类能够出现的任何地方。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 违反里氏替换
|
||
class Bird {
|
||
public void fly() {
|
||
System.out.println("Flying");
|
||
}
|
||
}
|
||
|
||
class Penguin extends Bird {
|
||
@Override
|
||
public void fly() {
|
||
throw new UnsupportedOperationException("企鹅不会飞");
|
||
}
|
||
}
|
||
|
||
// ✅ 符合里氏替换
|
||
class Bird { }
|
||
|
||
class FlyingBird extends Bird {
|
||
public void fly() {
|
||
System.out.println("Flying");
|
||
}
|
||
}
|
||
|
||
class Penguin extends Bird {
|
||
public void swim() {
|
||
System.out.println("Swimming");
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **接口隔离原则(Interface Segregation Principle)**
|
||
|
||
**定义**:客户端不应该依赖它不需要的接口。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 接口过于臃肿
|
||
interface Animal {
|
||
void fly();
|
||
void swim();
|
||
void run();
|
||
}
|
||
|
||
// ✅ 拆分接口
|
||
interface Flyable {
|
||
void fly();
|
||
}
|
||
|
||
interface Swimmable {
|
||
void swim();
|
||
}
|
||
|
||
interface Runnable {
|
||
void run();
|
||
}
|
||
|
||
class Duck implements Flyable, Swimmable, Runnable {
|
||
@Override
|
||
public void fly() { }
|
||
|
||
@Override
|
||
public void swim() { }
|
||
|
||
@Override
|
||
public void run() { }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **依赖倒置原则(Dependency Inversion Principle)**
|
||
|
||
**定义**:高层模块不应该依赖低层模块,两者都应该依赖抽象。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 高层依赖低层
|
||
class OrderService {
|
||
private MySQLDatabase database = new MySQLDatabase(); // 直接依赖具体实现
|
||
|
||
public void saveOrder(Order order) {
|
||
database.save(order);
|
||
}
|
||
}
|
||
|
||
// ✅ 依赖抽象
|
||
interface Database {
|
||
void save(Object obj);
|
||
}
|
||
|
||
class MySQLDatabase implements Database {
|
||
@Override
|
||
public void save(Object obj) {
|
||
// MySQL 实现
|
||
}
|
||
}
|
||
|
||
class OrderService {
|
||
private final Database database;
|
||
|
||
public OrderService(Database database) {
|
||
this.database = database; // 依赖注入
|
||
}
|
||
|
||
public void saveOrder(Order order) {
|
||
database.save(order);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **迪米特法则(Law of Demeter / Least Knowledge Principle)**
|
||
|
||
**定义**:一个对象应该对其他对象有最少的了解。
|
||
|
||
**示例**:
|
||
```java
|
||
// ❌ 违反迪米特法则
|
||
class Customer {
|
||
private Order order;
|
||
|
||
public void printOrderDetails() {
|
||
System.out.println(order.getItem().getProduct().getName());
|
||
// Customer → Order → Item → Product(了解太多)
|
||
}
|
||
}
|
||
|
||
// ✅ 符合迪米特法则
|
||
class Customer {
|
||
private Order order;
|
||
|
||
public void printOrderDetails() {
|
||
System.out.println(order.getProductName());
|
||
}
|
||
}
|
||
|
||
class Order {
|
||
private Item item;
|
||
|
||
public String getProductName() {
|
||
return item.getProduct().getName();
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 单例模式
|
||
|
||
#### **实现方式**
|
||
|
||
##### **方式 1:饿汉式(线程安全)**
|
||
|
||
```java
|
||
public class Singleton {
|
||
private static final Singleton INSTANCE = new Singleton();
|
||
|
||
private Singleton() { }
|
||
|
||
public static Singleton getInstance() {
|
||
return INSTANCE;
|
||
}
|
||
}
|
||
```
|
||
|
||
**优点**:简单、线程安全
|
||
**缺点**:类加载时初始化,可能浪费资源
|
||
|
||
---
|
||
|
||
##### **方式 2:懒汉式(线程不安全)**
|
||
|
||
```java
|
||
public class Singleton {
|
||
private static Singleton instance;
|
||
|
||
private Singleton() { }
|
||
|
||
public static Singleton getInstance() {
|
||
if (instance == null) {
|
||
instance = new Singleton();
|
||
}
|
||
return instance;
|
||
}
|
||
}
|
||
```
|
||
|
||
**问题**:线程不安全
|
||
|
||
---
|
||
|
||
##### **方式 3:懒汉式 + synchronized(线程安全但性能差)**
|
||
|
||
```java
|
||
public class Singleton {
|
||
private static Singleton instance;
|
||
|
||
private Singleton() { }
|
||
|
||
public static synchronized Singleton getInstance() {
|
||
if (instance == null) {
|
||
instance = new Singleton();
|
||
}
|
||
return instance;
|
||
}
|
||
}
|
||
```
|
||
|
||
**问题**:每次调用都需要加锁,性能差
|
||
|
||
---
|
||
|
||
##### **方式 4:双重检查锁定(推荐)**
|
||
|
||
```java
|
||
public class Singleton {
|
||
// volatile 禁止指令重排序
|
||
private static volatile Singleton instance;
|
||
|
||
private Singleton() { }
|
||
|
||
public static Singleton getInstance() {
|
||
if (instance == null) { // 第一次检查(无锁)
|
||
synchronized (Singleton.class) {
|
||
if (instance == null) { // 第二次检查(有锁)
|
||
instance = new Singleton();
|
||
}
|
||
}
|
||
}
|
||
return instance;
|
||
}
|
||
}
|
||
```
|
||
|
||
**为什么需要 volatile?**
|
||
```java
|
||
instance = new Singleton();
|
||
// 分三步:
|
||
// 1. 分配内存
|
||
// 2. 初始化对象
|
||
// 3. 将 instance 指向内存
|
||
|
||
// 指令重排序后可能是:1 → 3 → 2
|
||
// 线程 A 执行了 1、3,线程 B 发现 instance 不为 null,但对象未初始化!
|
||
```
|
||
|
||
---
|
||
|
||
##### **方式 5:静态内部类(推荐)**
|
||
|
||
```java
|
||
public class Singleton {
|
||
private Singleton() { }
|
||
|
||
private static class Holder {
|
||
private static final Singleton INSTANCE = new Singleton();
|
||
}
|
||
|
||
public static Singleton getInstance() {
|
||
return Holder.INSTANCE;
|
||
}
|
||
}
|
||
```
|
||
|
||
**优点**:
|
||
- 延迟加载(调用 getInstance 时才初始化)
|
||
- 线程安全(类加载机制保证)
|
||
- 性能好(无锁)
|
||
|
||
---
|
||
|
||
##### **方式 6:枚举(最佳实践)**
|
||
|
||
```java
|
||
public enum Singleton {
|
||
INSTANCE;
|
||
|
||
public void doSomething() {
|
||
// 业务方法
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
Singleton.INSTANCE.doSomething();
|
||
```
|
||
|
||
**优点**:
|
||
- 线程安全(JVM 保证)
|
||
- 防止反射攻击
|
||
- 防止序列化破坏
|
||
|
||
---
|
||
|
||
#### **单例模式的问题**
|
||
|
||
**1. 反射破坏单例**:
|
||
```java
|
||
Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
|
||
constructor.setAccessible(true);
|
||
Singleton instance1 = constructor.newInstance();
|
||
Singleton instance2 = constructor.newInstance();
|
||
// instance1 != instance2(单例被破坏)
|
||
```
|
||
|
||
**解决**:
|
||
```java
|
||
private Singleton() {
|
||
if (Holder.INSTANCE != null) {
|
||
throw new RuntimeException("不允许创建多个实例");
|
||
}
|
||
}
|
||
```
|
||
|
||
**2. 序列化破坏单例**:
|
||
```java
|
||
Singleton instance1 = Singleton.getInstance();
|
||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||
oos.writeObject(instance1);
|
||
|
||
ObjectInputStream ois = new ObjectInputStream(
|
||
new ByteArrayInputStream(bos.toByteArray())
|
||
);
|
||
Singleton instance2 = (Singleton) ois.readObject();
|
||
// instance1 != instance2(单例被破坏)
|
||
```
|
||
|
||
**解决**:
|
||
```java
|
||
public class Singleton implements Serializable {
|
||
private Singleton() { }
|
||
|
||
private static class Holder {
|
||
private static final Singleton INSTANCE = new Singleton();
|
||
}
|
||
|
||
// 反序列化时返回单例
|
||
private Object readResolve() {
|
||
return Holder.INSTANCE;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 工厂模式
|
||
|
||
#### **简单工厂**
|
||
|
||
```java
|
||
// 产品接口
|
||
interface Payment {
|
||
void pay(int amount);
|
||
}
|
||
|
||
// 具体产品
|
||
class Alipay implements Payment {
|
||
@Override
|
||
public void pay(int amount) {
|
||
System.out.println("支付宝支付:" + amount);
|
||
}
|
||
}
|
||
|
||
class WechatPay implements Payment {
|
||
@Override
|
||
public void pay(int amount) {
|
||
System.out.println("微信支付:" + amount);
|
||
}
|
||
}
|
||
|
||
// 工厂类
|
||
class PaymentFactory {
|
||
public static Payment createPayment(String type) {
|
||
switch (type) {
|
||
case "alipay":
|
||
return new Alipay();
|
||
case "wechat":
|
||
return new WechatPay();
|
||
default:
|
||
throw new IllegalArgumentException("不支持支付方式");
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
Payment payment = PaymentFactory.createPayment("alipay");
|
||
payment.pay(100);
|
||
```
|
||
|
||
**问题**:新增支付方式需要修改工厂类(违反开闭原则)
|
||
|
||
---
|
||
|
||
#### **工厂方法**
|
||
|
||
```java
|
||
// 工厂接口
|
||
interface PaymentFactory {
|
||
Payment createPayment();
|
||
}
|
||
|
||
// 具体工厂
|
||
class AlipayFactory implements PaymentFactory {
|
||
@Override
|
||
public Payment createPayment() {
|
||
return new Alipay();
|
||
}
|
||
}
|
||
|
||
class WechatPayFactory implements PaymentFactory {
|
||
@Override
|
||
public Payment createPayment() {
|
||
return new WechatPay();
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
PaymentFactory factory = new AlipayFactory();
|
||
Payment payment = factory.createPayment();
|
||
payment.pay(100);
|
||
```
|
||
|
||
**优点**:符合开闭原则(新增支付方式无需修改代码)
|
||
|
||
---
|
||
|
||
#### **抽象工厂**
|
||
|
||
**场景**:跨平台 UI 工具包
|
||
|
||
```java
|
||
// 抽象产品
|
||
interface Button {
|
||
void render();
|
||
}
|
||
|
||
interface Checkbox {
|
||
void render();
|
||
}
|
||
|
||
// 具体产品(Windows 风格)
|
||
class WindowsButton implements Button {
|
||
@Override
|
||
public void render() {
|
||
System.out.println("Windows 按钮");
|
||
}
|
||
}
|
||
|
||
class WindowsCheckbox implements Checkbox {
|
||
@Override
|
||
public void render() {
|
||
System.out.println("Windows 复选框");
|
||
}
|
||
}
|
||
|
||
// 具体产品(Mac 风格)
|
||
class MacButton implements Button {
|
||
@Override
|
||
public void render() {
|
||
System.out.println("Mac 按钮");
|
||
}
|
||
}
|
||
|
||
class MacCheckbox implements Checkbox {
|
||
@Override
|
||
public void render() {
|
||
System.out.println("Mac 复选框");
|
||
}
|
||
}
|
||
|
||
// 抽象工厂
|
||
interface GUIFactory {
|
||
Button createButton();
|
||
Checkbox createCheckbox();
|
||
}
|
||
|
||
// 具体工厂
|
||
class WindowsFactory implements GUIFactory {
|
||
@Override
|
||
public Button createButton() {
|
||
return new WindowsButton();
|
||
}
|
||
|
||
@Override
|
||
public Checkbox createCheckbox() {
|
||
return new WindowsCheckbox();
|
||
}
|
||
}
|
||
|
||
class MacFactory implements GUIFactory {
|
||
@Override
|
||
public Button createButton() {
|
||
return new MacButton();
|
||
}
|
||
|
||
@Override
|
||
public Checkbox createCheckbox() {
|
||
return new MacCheckbox();
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
GUIFactory factory = new WindowsFactory();
|
||
Button button = factory.createButton();
|
||
Checkbox checkbox = factory.createCheckbox();
|
||
button.render();
|
||
checkbox.render();
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 观察者模式
|
||
|
||
#### **原理**
|
||
|
||
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都得到通知并自动更新。
|
||
|
||
---
|
||
|
||
#### **Java 实现**
|
||
|
||
```java
|
||
// 观察者接口
|
||
interface Observer {
|
||
void update(String message);
|
||
}
|
||
|
||
// 被观察者(主题)
|
||
interface Subject {
|
||
void attach(Observer observer);
|
||
void detach(Observer observer);
|
||
void notifyObservers();
|
||
}
|
||
|
||
// 具体主题
|
||
class MessageQueue implements Subject {
|
||
private List<Observer> observers = new ArrayList<>();
|
||
private String message;
|
||
|
||
@Override
|
||
public void attach(Observer observer) {
|
||
observers.add(observer);
|
||
}
|
||
|
||
@Override
|
||
public void detach(Observer observer) {
|
||
observers.remove(observer);
|
||
}
|
||
|
||
@Override
|
||
public void notifyObservers() {
|
||
for (Observer observer : observers) {
|
||
observer.update(message);
|
||
}
|
||
}
|
||
|
||
public void setMessage(String message) {
|
||
this.message = message;
|
||
notifyObservers();
|
||
}
|
||
}
|
||
|
||
// 具体观察者
|
||
class EmailNotifier implements Observer {
|
||
@Override
|
||
public void update(String message) {
|
||
System.out.println("发送邮件:" + message);
|
||
}
|
||
}
|
||
|
||
class SMSNotifier implements Observer {
|
||
@Override
|
||
public void update(String message) {
|
||
System.out.println("发送短信:" + message);
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
MessageQueue queue = new MessageQueue();
|
||
queue.attach(new EmailNotifier());
|
||
queue.attach(new SMSNotifier());
|
||
|
||
queue.setMessage("新订单创建");
|
||
```
|
||
|
||
---
|
||
|
||
#### **Spring 事件机制(观察者模式)**
|
||
|
||
```java
|
||
// 1. 定义事件
|
||
class OrderCreatedEvent extends ApplicationEvent {
|
||
private final Order order;
|
||
|
||
public OrderCreatedEvent(Object source, Order order) {
|
||
super(source);
|
||
this.order = order;
|
||
}
|
||
|
||
public Order getOrder() {
|
||
return order;
|
||
}
|
||
}
|
||
|
||
// 2. 定义监听器
|
||
@Component
|
||
class OrderEmailListener {
|
||
@EventListener
|
||
public void handleOrderCreated(OrderCreatedEvent event) {
|
||
System.out.println("发送邮件:" + event.getOrder());
|
||
}
|
||
}
|
||
|
||
@Component
|
||
class OrderSMSListener {
|
||
@EventListener
|
||
public void handleOrderCreated(OrderCreatedEvent event) {
|
||
System.out.println("发送短信:" + event.getOrder());
|
||
}
|
||
}
|
||
|
||
// 3. 发布事件
|
||
@Service
|
||
class OrderService {
|
||
@Autowired
|
||
private ApplicationEventPublisher eventPublisher;
|
||
|
||
public void createOrder(Order order) {
|
||
// 保存订单
|
||
orderRepository.save(order);
|
||
|
||
// 发布事件
|
||
eventPublisher.publishEvent(new OrderCreatedEvent(this, order));
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 策略模式
|
||
|
||
#### **场景:计算不同类型的折扣**
|
||
|
||
```java
|
||
// 策略接口
|
||
interface DiscountStrategy {
|
||
double calculate(double price);
|
||
}
|
||
|
||
// 具体策略
|
||
class VipDiscount implements DiscountStrategy {
|
||
@Override
|
||
public double calculate(double price) {
|
||
return price * 0.8;
|
||
}
|
||
}
|
||
|
||
class SvipDiscount implements DiscountStrategy {
|
||
@Override
|
||
public double calculate(double price) {
|
||
return price * 0.7;
|
||
}
|
||
}
|
||
|
||
class NormalDiscount implements DiscountStrategy {
|
||
@Override
|
||
public double calculate(double price) {
|
||
return price;
|
||
}
|
||
}
|
||
|
||
// 上下文
|
||
class OrderService {
|
||
private Map<String, DiscountStrategy> strategyMap = new HashMap<>();
|
||
|
||
@PostConstruct
|
||
public void init() {
|
||
strategyMap.put("VIP", new VipDiscount());
|
||
strategyMap.put("SVIP", new SvipDiscount());
|
||
strategyMap.put("NORMAL", new NormalDiscount());
|
||
}
|
||
|
||
public double calculatePrice(String userType, double price) {
|
||
DiscountStrategy strategy = strategyMap.get(userType);
|
||
if (strategy == null) {
|
||
throw new IllegalArgumentException("不支持的用户类型");
|
||
}
|
||
return strategy.calculate(price);
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
OrderService orderService = new OrderService();
|
||
double price = orderService.calculatePrice("VIP", 100);
|
||
```
|
||
|
||
---
|
||
|
||
#### **Spring 实现策略模式**
|
||
|
||
```java
|
||
// 策略接口
|
||
public interface PaymentStrategy {
|
||
void pay(int amount);
|
||
|
||
// 获取策略类型
|
||
String getType();
|
||
}
|
||
|
||
// 具体策略(标注为 Spring Bean)
|
||
@Component
|
||
public class AlipayStrategy implements PaymentStrategy {
|
||
@Override
|
||
public void pay(int amount) {
|
||
System.out.println("支付宝支付:" + amount);
|
||
}
|
||
|
||
@Override
|
||
public String getType() {
|
||
return "alipay";
|
||
}
|
||
}
|
||
|
||
@Component
|
||
public class WechatPayStrategy implements PaymentStrategy {
|
||
@Override
|
||
public void pay(int amount) {
|
||
System.out.println("微信支付:" + amount);
|
||
}
|
||
|
||
@Override
|
||
public String getType() {
|
||
return "wechat";
|
||
}
|
||
}
|
||
|
||
// 策略工厂
|
||
@Service
|
||
public class PaymentService {
|
||
private final Map<String, PaymentStrategy> strategyMap;
|
||
|
||
// 构造器注入所有策略
|
||
public PaymentService(List<PaymentStrategy> strategies) {
|
||
this.strategyMap = strategies.stream()
|
||
.collect(Collectors.toMap(
|
||
PaymentStrategy::getType,
|
||
Function.identity()
|
||
));
|
||
}
|
||
|
||
public void pay(String type, int amount) {
|
||
PaymentStrategy strategy = strategyMap.get(type);
|
||
if (strategy == null) {
|
||
throw new IllegalArgumentException("不支持的支付方式");
|
||
}
|
||
strategy.pay(amount);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 装饰器模式 vs 代理模式
|
||
|
||
#### **装饰器模式**
|
||
|
||
**目的**:动态地给对象添加功能
|
||
|
||
**示例**:
|
||
```java
|
||
// 组件接口
|
||
interface Coffee {
|
||
double cost();
|
||
}
|
||
|
||
// 具体组件
|
||
class SimpleCoffee implements Coffee {
|
||
@Override
|
||
public double cost() {
|
||
return 10;
|
||
}
|
||
}
|
||
|
||
// 装饰器
|
||
class MilkDecorator implements Coffee {
|
||
private final Coffee coffee;
|
||
|
||
public MilkDecorator(Coffee coffee) {
|
||
this.coffee = coffee;
|
||
}
|
||
|
||
@Override
|
||
public double cost() {
|
||
return coffee.cost() + 2; // 加奶 2 元
|
||
}
|
||
}
|
||
|
||
class SugarDecorator implements Coffee {
|
||
private final Coffee coffee;
|
||
|
||
public SugarDecorator(Coffee coffee) {
|
||
this.coffee = coffee;
|
||
}
|
||
|
||
@Override
|
||
public double cost() {
|
||
return coffee.cost() + 1; // 加糖 1 元
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
Coffee coffee = new SimpleCoffee();
|
||
coffee = new MilkDecorator(coffee); // 加奶
|
||
coffee = new SugarDecorator(coffee); // 加糖
|
||
System.out.println(coffee.cost()); // 10 + 2 + 1 = 13
|
||
```
|
||
|
||
---
|
||
|
||
#### **代理模式**
|
||
|
||
**目的**:控制对对象的访问
|
||
|
||
**静态代理**:
|
||
```java
|
||
// 接口
|
||
interface OrderService {
|
||
void createOrder(Order order);
|
||
}
|
||
|
||
// 真实对象
|
||
class OrderServiceImpl implements OrderService {
|
||
@Override
|
||
public void createOrder(Order order) {
|
||
System.out.println("创建订单:" + order);
|
||
}
|
||
}
|
||
|
||
// 代理对象
|
||
class OrderServiceProxy implements OrderService {
|
||
private final OrderService orderService;
|
||
|
||
public OrderServiceProxy(OrderService orderService) {
|
||
this.orderService = orderService;
|
||
}
|
||
|
||
@Override
|
||
public void createOrder(Order order) {
|
||
// 前置增强
|
||
System.out.println("权限检查");
|
||
|
||
// 调用真实对象
|
||
orderService.createOrder(order);
|
||
|
||
// 后置增强
|
||
System.out.println("日志记录");
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
OrderService proxy = new OrderServiceProxy(new OrderServiceImpl());
|
||
proxy.createOrder(new Order());
|
||
```
|
||
|
||
---
|
||
|
||
**动态代理(JDK)**:
|
||
```java
|
||
class ProxyHandler implements InvocationHandler {
|
||
private final Object target;
|
||
|
||
public ProxyHandler(Object target) {
|
||
this.target = target;
|
||
}
|
||
|
||
@Override
|
||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||
// 前置增强
|
||
System.out.println("权限检查");
|
||
|
||
// 调用真实对象
|
||
Object result = method.invoke(target, args);
|
||
|
||
// 后置增强
|
||
System.out.println("日志记录");
|
||
|
||
return result;
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
OrderService realService = new OrderServiceImpl();
|
||
OrderService proxyService = (OrderService) Proxy.newProxyInstance(
|
||
realService.getClass().getClassLoader(),
|
||
realService.getClass().getInterfaces(),
|
||
new ProxyHandler(realService)
|
||
);
|
||
proxyService.createOrder(new Order());
|
||
```
|
||
|
||
---
|
||
|
||
#### **对比**
|
||
|
||
| 特性 | 装饰器模式 | 代理模式 |
|
||
|------|-----------|---------|
|
||
| **目的** | 增强功能 | 控制访问 |
|
||
| **关注点** | 功能扩展 | 访问控制 |
|
||
| **透明性** | 对客户端透明 | 客户端可能知道代理存在 |
|
||
| **示例** | Java I/O Streams | Spring AOP |
|
||
|
||
---
|
||
|
||
### 7. 实际项目应用
|
||
|
||
#### **Spring 中的设计模式**
|
||
|
||
1. **工厂模式**:`BeanFactory`、`ApplicationContext`
|
||
2. **单例模式**:Spring Bean(默认单例)
|
||
3. **代理模式**:AOP、事务管理
|
||
4. **观察者模式**:ApplicationEvent、ApplicationListener
|
||
5. **策略模式**:`Resource`(不同资源加载策略)
|
||
6. **模板方法模式**:`JdbcTemplate`、`RestTemplate`
|
||
7. **适配器模式**:`HandlerAdapter`
|
||
8. **责任链模式**:Filter Chain、Interceptor Chain
|
||
|
||
---
|
||
|
||
### 8. 阿里 P7 加分项
|
||
|
||
**深度理解**:
|
||
- 理解设计模式的适用场景和权衡
|
||
- 理解设计模式与重构的关系
|
||
- 理解设计模式在开源框架中的应用
|
||
|
||
**实战经验**:
|
||
- 有使用设计模式重构代码的经验
|
||
- 有设计模式误用的经验和教训
|
||
- 能根据业务特点选择合适的设计模式
|
||
|
||
**架构能力**:
|
||
- 能设计可扩展、可维护的架构
|
||
- 能识别代码中的坏味道并重构
|
||
- 能在团队中推广设计模式最佳实践
|