Appearance
设计模式概述
23 种设计模式
┌─────────────────────────────────────────────────────────────────┐
│ 23 种设计模式 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 创建型模式 (5) │ │
│ │ 单例 │ 工厂 │ 抽象工厂 │ 建造者 │ 原型 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 结构型模式 (7) │ │
│ │ 适配器 │ 桥接 │ 装饰器 │ 代理 │ 外观 │ ... │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 行为型模式 (11) │ │
│ │ 策略 │ 观察者 │ 命令 │ 模板方法 │ 责任链 │ ... │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘设计原则
SOLID 原则
| 原则 | 说明 | 目的 |
|---|---|---|
| Single Responsibility | 单一职责 | 一个类只做一件事 |
| Open/Closed | 开闭原则 | 对扩展开放,对修改关闭 |
| Liskov Substitution | 里氏替换 | 子类可以替换父类 |
| Interface Segregation | 接口隔离 | 接口要小而专 |
| Dependency Inversion | 依赖倒置 | 面向接口编程 |
┌─────────────────────────────────────────────────────────────────┐
│ 设计原则速记口诀 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 单一职责:各司其职 │
│ 开闭原则:不改源码,加新功能 │
│ 里氏替换:子类是父类的子集 │
│ 接口隔离:大接口拆小 │
│ 依赖倒置:依赖抽象,不依赖具体 │
│ │
└─────────────────────────────────────────────────────────────────┘创建型模式
单例模式 (Singleton)
意图:保证一个类只有一个实例,并提供全局访问点。
java
// 饿汉式(线程安全,推荐)
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}
// 懒汉式(双重检查锁)
public class Singleton {
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;
}
}
// 枚举式(最佳实践,防止反射攻击)
public enum Singleton {
INSTANCE;
public void method() { }
}应用场景:
- 数据库连接池
- 日志管理器
- 全局配置对象
工厂模式 (Factory)
意图:定义创建对象的接口,让子类决定实例化哪个类。
java
// 简单工厂(不属于23种设计模式)
public class SimpleFactory {
public static Product create(String type) {
switch (type) {
case "A": return new ProductA();
case "B": return new ProductB();
default: throw new IllegalArgumentException();
}
}
}
// 工厂方法
public interface Factory {
Product create();
}
public class FactoryA implements Factory {
@Override
public Product create() {
return new ProductA();
}
}
public class FactoryB implements Factory {
@Override
public Product create() {
return new ProductB();
}
}
// 使用
Factory factory = new FactoryA();
Product product = factory.create();抽象工厂模式 (Abstract Factory)
意图:提供一个创建一系列相关对象的接口。
java
// 抽象工厂
public interface AbstractFactory {
Chair createChair();
Sofa createSofa();
}
// 具体工厂
public class ModernFactory implements AbstractFactory {
@Override
public Chair createChair() {
return new ModernChair();
}
@Override
public Sofa createSofa() {
return new ModernSofa();
}
}
public class VictorianFactory implements AbstractFactory {
@Override
public Chair createChair() {
return new VictorianChair();
}
@Override
public Sofa createSofa() {
return new VictorianSofa();
}
}建造者模式 (Builder)
意图:分步骤构建复杂对象。
java
// 建造者
public class UserBuilder {
private String name;
private int age;
private String email;
private String phone;
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder email(String email) {
this.email = email;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
// 使用
User user = new UserBuilder()
.name("张三")
.age(25)
.email("zhang@example.com")
.phone("13800138000")
.build();应用场景:
- StringBuilder
- Lombok @Builder
- MyBatis SqlSessionFactoryBuilder
原型模式 (Prototype)
意图:通过复制现有对象创建新对象。
java
// 原型接口
public interface Prototype {
Prototype clone();
}
// 具体原型
public class User implements Prototype {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public User clone() {
return new User(this.name, this.age);
}
}
// 使用
User user1 = new User("张三", 25);
User user2 = user1.clone(); // 复制应用场景:
- Java
Cloneable接口 - Spring
Prototypescope
结构型模式
适配器模式 (Adapter)
意图:将不兼容的接口转换为可兼容的接口。
java
// 目标接口
public interface Target {
void request();
}
// 适配者
public class Adaptee {
public void specificRequest() {
System.out.println("适配者的方法");
}
}
// 适配器
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 使用
Target target = new Adapter(new Adaptee());
target.request(); // 输出:适配者的方法应用场景:
- Spring AOP 适配通知
- Spring MVC HandlerAdapter
装饰器模式 (Decorator)
意图:动态地给对象添加职责。
java
// 组件接口
public interface Coffee {
String getDescription();
double getCost();
}
// 基础组件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double getCost() {
return 10;
}
}
// 装饰器基类
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Milk";
}
@Override
double getCost() {
return coffee.getCost() + 2;
}
}
// 使用
Coffee coffee = new MilkDecorator(new SimpleCoffee());
System.out.println(coffee.getDescription()); // Simple Coffee, Milk
System.out.println(coffee.getCost()); // 12应用场景:
- Java I/O 流(BufferedInputStream 装饰 FileInputStream)
- Spring TransactionAwareConnectionProxy
代理模式 (Proxy)
意图:为其他对象提供一种代理以控制访问。
java
// 主题接口
public interface Subject {
void request();
}
// 真实主题
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject 处理请求");
}
}
// 代理
public class Proxy implements Subject {
private RealSubject realSubject;
@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
beforeRequest();
realSubject.request();
afterRequest();
}
private void beforeRequest() {
System.out.println("代理:前置处理");
}
private void afterRequest() {
System.out.println("代理:后置处理");
}
}
// 使用
Subject subject = new Proxy();
subject.request();应用场景:
- Spring AOP(动态代理/JDK代理/CGLIB)
- MyBatis 懒加载
- RPC 远程代理
外观模式 (Facade)
意图:提供统一接口,封装子系统的一组接口。
java
// 子系统
public class CPU {
public void start() { System.out.println("CPU 启动"); }
public void shutdown() { System.out.println("CPU 关闭"); }
}
public class Memory {
public void start() { System.out.println("内存 启动"); }
public void shutdown() { System.out.println("内存 关闭"); }
}
public class Disk {
public void start() { System.out.println("硬盘 启动"); }
public void shutdown() { System.out.println("硬盘 关闭"); }
}
// 外观
public class ComputerFacade {
private CPU cpu = new CPU();
private Memory memory = new Memory();
private Disk disk = new Disk();
public void start() {
cpu.start();
memory.start();
disk.start();
}
public void shutdown() {
disk.shutdown();
memory.shutdown();
cpu.shutdown();
}
}
// 使用 - 简化调用
new ComputerFacade().start();行为型模式
策略模式 (Strategy)
意图:定义一系列算法,让它们可以相互替换。
java
// 策略接口
public interface PaymentStrategy {
void pay(double amount);
}
// 具体策略
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("支付宝支付:" + amount);
}
}
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("微信支付:" + amount);
}
}
// 上下文
public class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void pay(double amount) {
strategy.pay(amount);
}
}
// 使用
PaymentContext ctx = new PaymentContext(new AlipayStrategy());
ctx.pay(100);观察者模式 (Observer)
意图:定义一对多依赖,当一个对象变化时通知所有依赖。
java
// 观察者接口
public interface Observer {
void update(String message);
}
// 具体观察者
public class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到消息:" + message);
}
}
// 被观察者
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// 使用
Subject subject = new Subject();
subject.attach(new User("张三"));
subject.attach(new User("李四"));
subject.notifyObservers("发布新消息");应用场景:
- JDK
Observable/Observer - Spring
ApplicationEvent - GUI 事件处理
模板方法模式 (Template Method)
意图:定义算法骨架,某些步骤延迟到子类。
java
// 抽象模板
public abstract class Game {
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
}
// 具体实现
public class FootballGame extends Game {
@Override
void initialize() {
System.out.println("初始化足球游戏");
}
@Override
void startPlay() {
System.out.println("开始足球比赛");
}
@Override
void endPlay() {
System.out.println("足球比赛结束");
}
}
// 使用
Game game = new FootballGame();
game.play();应用场景:
- Spring
JdbcTemplate - Spring
HibernateTemplate - Apache `Abst
...
private void connect() { System.out.println("连接数据库"); }
@Override
protected void execute() {
System.out.println("执行查询");
}
@Override
protected void disconnect() {
System.out.println("断开数据库");
}
}
**核心知识点**:
| 模式 | 面试频率 | 实战重要性 |
|------|---------|-----------|
| 单例模式 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 工厂模式 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 建造者模式 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 代理模式 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 策略模式 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 观察者模式 | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 模板方法模式 | ⭐⭐⭐ | ⭐⭐⭐ |