设计模式是软件开发中经过验证的最佳实践,面向对象设计原则是编写可维护、可扩展代码的指导方针。本文系统总结Java中常用的设计模式和SOLID等设计原则。
面向对象设计原则
SOLID原则概览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ┌──────────────────────────────────────────────────────────────────┐ │ SOLID原则 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ S - Single Responsibility Principle 单一职责原则 │ │ 一个类只负责一项职责 │ │ │ │ O - Open/Closed Principle 开闭原则 │ │ 对扩展开放,对修改关闭 │ │ │ │ L - Liskov Substitution Principle 里氏替换原则 │ │ 子类可以替换父类出现的任何地方 │ │ │ │ I - Interface Segregation Principle 接口隔离原则 │ │ 使用多个专门接口,而非单一总接口 │ │ │ │ D - Dependency Inversion Principle 依赖倒置原则 │ │ 依赖抽象而非具体实现 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
单一职责原则(SRP)
一个类应该只有一个引起它变化的原因。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class User { private String name; private String email;
public void saveToDatabase() { } public void sendEmail() { } public String generateReport() { } }
public class User { private String name; private String email; }
public class UserRepository { public void save(User user) { } }
public class EmailService { public void sendEmail(User user, String content) { } }
public class UserReportGenerator { public String generate(User user) { } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌──────────────────────────────────────────────────────────────────┐ │ 单一职责原则 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 违反SRP: 遵循SRP: │ │ ┌─────────────────┐ ┌──────────┐ │ │ │ User │ │ User │ │ │ │─────────────────│ └──────────┘ │ │ │ saveToDatabase()│ │ │ │ │ sendEmail() │ ┌─────────────┼─────────────┐ │ │ │ generateReport()│ ▼ ▼ ▼ │ │ └─────────────────┘ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │UserRepo │ │EmailSvc │ │ReportGen │ │ │ 一个类三个变化原因 └──────────┘ └──────────┘ └──────────┘ │ │ 每个类一个变化原因 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
开闭原则(OCP)
软件实体应该对扩展开放,对修改关闭。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class AreaCalculator { public double calculate(Object shape) { if (shape instanceof Rectangle) { Rectangle r = (Rectangle) shape; return r.width * r.height; } else if (shape instanceof Circle) { Circle c = (Circle) shape; return Math.PI * c.radius * c.radius; } return 0; } }
public interface Shape { double area(); }
public class Rectangle implements Shape { private double width, height;
@Override public double area() { return width * height; } }
public class Circle implements Shape { private double radius;
@Override public double area() { return Math.PI * radius * radius; } }
public class Triangle implements Shape { private double base, height;
@Override public double area() { return 0.5 * base * height; } }
public class AreaCalculator { public double calculate(Shape shape) { return shape.area(); } }
|
里氏替换原则(LSP)
子类对象能够替换父类对象出现的任何地方,且程序行为不变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class Rectangle { protected int width; protected int height;
public void setWidth(int width) { this.width = width; } public void setHeight(int height) { this.height = height; } public int getArea() { return width * height; } }
public class Square extends Rectangle { @Override public void setWidth(int width) { this.width = width; this.height = width; }
@Override public void setHeight(int height) { this.width = height; this.height = height; } }
public void resize(Rectangle r) { r.setWidth(5); r.setHeight(10); assert r.getArea() == 50; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| ┌──────────────────────────────────────────────────────────────────┐ │ 里氏替换原则 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 正确做法:使用组合或共同抽象 │ │ │ │ ┌──────────────┐ │ │ │ Shape │ │ │ │──────────────│ │ │ │ + getArea() │ │ │ └──────┬───────┘ │ │ │ │ │ ┌───────────┴───────────┐ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Rectangle │ │ Square │ │ │ │──────────────│ │──────────────│ │ │ │ width,height │ │ side │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ LSP核心:子类不应该破坏父类的契约(前置条件、后置条件、不变量) │ │ │ └──────────────────────────────────────────────────────────────────┘
|
接口隔离原则(ISP)
客户端不应该被迫依赖它不使用的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public interface Worker { void work(); void eat(); void sleep(); }
public class Robot implements Worker { @Override public void work() { }
@Override public void eat() { }
@Override public void sleep() { } }
public interface Workable { void work(); }
public interface Eatable { void eat(); }
public interface Sleepable { void sleep(); }
public class Human implements Workable, Eatable, Sleepable { @Override public void work() { }
@Override public void eat() { }
@Override public void sleep() { } }
public class Robot implements Workable { @Override public void work() { } }
|
依赖倒置原则(DIP)
高层模块不应该依赖低层模块,两者都应该依赖抽象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class OrderService { private MySQLDatabase database = new MySQLDatabase(); private EmailSender emailSender = new EmailSender();
public void createOrder(Order order) { database.save(order); emailSender.send(order.getUserEmail(), "订单创建成功"); } }
public interface Database { void save(Object entity); }
public interface NotificationService { void send(String to, String message); }
public class OrderService { private final Database database; private final NotificationService notificationService;
public OrderService(Database database, NotificationService notificationService) { this.database = database; this.notificationService = notificationService; }
public void createOrder(Order order) { database.save(order); notificationService.send(order.getUserEmail(), "订单创建成功"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| ┌──────────────────────────────────────────────────────────────────┐ │ 依赖倒置原则 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 违反DIP: 遵循DIP: │ │ │ │ ┌────────────────┐ ┌────────────────┐ │ │ │ OrderService │ │ OrderService │ │ │ │ (高层) │ │ (高层) │ │ │ └───────┬────────┘ └───────┬────────┘ │ │ │ 依赖 │ 依赖 │ │ ▼ ▼ │ │ ┌────────────────┐ ┌────────────────┐ │ │ │ MySQLDatabase │ │ Database │ ◀─ 抽象 │ │ │ (低层) │ │ (interface) │ │ │ └────────────────┘ └───────┬────────┘ │ │ │ 实现 │ │ 高层直接依赖低层 ▼ │ │ 更换数据库需要修改高层 ┌────────────────┐ │ │ │ MySQLDatabase │ │ │ │ (低层) │ │ │ └────────────────┘ │ │ 更换数据库只需更换实现 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
其他重要原则
迪米特法则(最少知识原则)
一个对象应该对其他对象有最少的了解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Customer { private Wallet wallet; public Wallet getWallet() { return wallet; } }
public class Paperboy { public void collectMoney(Customer customer, double amount) { if (customer.getWallet().getMoney() >= amount) { customer.getWallet().subtractMoney(amount); } } }
public class Customer { private Wallet wallet;
public double pay(double amount) { if (wallet.getMoney() >= amount) { wallet.subtractMoney(amount); return amount; } return 0; } }
public class Paperboy { public void collectMoney(Customer customer, double amount) { double paid = customer.pay(amount); } }
|
合成复用原则
优先使用组合而非继承来达到复用目的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Car extends Engine { }
public class Car { private Engine engine;
public Car(Engine engine) { this.engine = engine; }
public void start() { engine.start(); } }
Car electricCar = new Car(new ElectricEngine()); Car gasCar = new Car(new GasEngine());
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ┌──────────────────────────────────────────────────────────────────┐ │ 继承 vs 组合 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 继承: │ │ • IS-A 关系(猫是动物) │ │ • 编译时确定,静态绑定 │ │ • 紧耦合,子类暴露父类细节 │ │ • 破坏封装性 │ │ │ │ 组合: │ │ • HAS-A 关系(汽车有引擎) │ │ • 运行时确定,动态绑定 │ │ • 松耦合,只依赖接口 │ │ • 保持封装性 │ │ │ │ 原则:优先使用组合,只在真正的IS-A关系时使用继承 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
设计模式概览
设计模式分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| ┌──────────────────────────────────────────────────────────────────┐ │ 23种设计模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 创建型模式(5种) 关注对象的创建 │ │ ───────────────────────────────────────────── │ │ • 单例模式(Singleton) 确保类只有一个实例 │ │ • 工厂方法(Factory Method) 定义创建对象的接口 │ │ • 抽象工厂(Abstract Factory)创建相关对象族 │ │ • 建造者(Builder) 分步骤构建复杂对象 │ │ • 原型(Prototype) 通过复制创建对象 │ │ │ │ 结构型模式(7种) 关注类和对象的组合 │ │ ───────────────────────────────────────────── │ │ • 适配器(Adapter) 转换接口 │ │ • 桥接(Bridge) 分离抽象和实现 │ │ • 组合(Composite) 树形结构 │ │ • 装饰器(Decorator) 动态添加职责 │ │ • 外观(Facade) 简化子系统接口 │ │ • 享元(Flyweight) 共享细粒度对象 │ │ • 代理(Proxy) 控制对象访问 │ │ │ │ 行为型模式(11种) 关注对象间的通信 │ │ ───────────────────────────────────────────── │ │ • 责任链(Chain of Responsibility) │ │ • 命令(Command) 封装请求 │ │ • 迭代器(Iterator) 遍历集合 │ │ • 中介者(Mediator) 封装对象交互 │ │ • 备忘录(Memento) 保存对象状态 │ │ • 观察者(Observer) 一对多依赖 │ │ • 状态(State) 状态决定行为 │ │ • 策略(Strategy) 封装算法 │ │ • 模板方法(Template Method) 定义算法骨架 │ │ • 访问者(Visitor) 分离数据结构与操作 │ │ • 解释器(Interpreter) 语言解释器 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
创建型模式
单例模式(Singleton)
确保一个类只有一个实例,并提供全局访问点。
饿汉式
1 2 3 4 5 6 7 8 9 10
| public class Singleton { private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return INSTANCE; } }
|
懒汉式(双重检查锁)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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; } }
|
静态内部类(推荐)
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private Singleton() {}
private static class Holder { private static final Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance() { return Holder.INSTANCE; } }
|
枚举(最佳实践)
1 2 3 4 5 6 7 8 9 10
| public enum Singleton { INSTANCE;
public void doSomething() { } }
Singleton.INSTANCE.doSomething();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──────────────────────────────────────────────────────────────────┐ │ 单例模式对比 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 实现方式 线程安全 延迟加载 防止反射 防止序列化 │ │ ─────────────────────────────────────────────────────────── │ │ 饿汉式 ✓ ✗ ✗ ✗ │ │ 懒汉式(同步方法) ✓ ✓ ✗ ✗ │ │ 双重检查锁 ✓ ✓ ✗ ✗ │ │ 静态内部类 ✓ ✓ ✗ ✗ │ │ 枚举 ✓ ✗ ✓ ✓ │ │ │ │ 推荐:枚举 > 静态内部类 > 双重检查锁 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
工厂方法模式(Factory Method)
定义创建对象的接口,让子类决定实例化哪个类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public interface Product { void use(); }
public class ConcreteProductA implements Product { @Override public void use() { System.out.println("使用产品A"); } }
public class ConcreteProductB implements Product { @Override public void use() { System.out.println("使用产品B"); } }
public interface Factory { Product createProduct(); }
public class FactoryA implements Factory { @Override public Product createProduct() { return new ConcreteProductA(); } }
public class FactoryB implements Factory { @Override public Product createProduct() { return new ConcreteProductB(); } }
Factory factory = new FactoryA(); Product product = factory.createProduct(); product.use();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ┌──────────────────────────────────────────────────────────────────┐ │ 工厂方法模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Factory │ │ Product │ │ │ │──────────────│ │──────────────│ │ │ │createProduct()│──────creates──▶│ use() │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ ┌───────┴───────┐ ┌───────┴───────┐ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │FactoryA │ │FactoryB │ │ProductA │ │ProductB │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 优点: │ │ • 符合开闭原则,新增产品只需新增工厂 │ │ • 解耦客户端和具体产品 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
抽象工厂模式(Abstract Factory)
提供创建一系列相关对象的接口,无需指定具体类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| public interface Button { void render(); }
public interface TextField { void render(); }
public class WindowsButton implements Button { @Override public void render() { System.out.println("Windows风格按钮"); } }
public class WindowsTextField implements TextField { @Override public void render() { System.out.println("Windows风格文本框"); } }
public class MacButton implements Button { @Override public void render() { System.out.println("Mac风格按钮"); } }
public class MacTextField implements TextField { @Override public void render() { System.out.println("Mac风格文本框"); } }
public interface GUIFactory { Button createButton(); TextField createTextField(); }
public class WindowsFactory implements GUIFactory { @Override public Button createButton() { return new WindowsButton(); }
@Override public TextField createTextField() { return new WindowsTextField(); } }
public class MacFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); }
@Override public TextField createTextField() { return new MacTextField(); } }
GUIFactory factory = new WindowsFactory(); Button button = factory.createButton(); TextField textField = factory.createTextField();
|
建造者模式(Builder)
将复杂对象的构建与表示分离,同样的构建过程可以创建不同的表示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public class Computer { private String cpu; private String ram; private String storage; private String gpu; private String screen;
private Computer(Builder builder) { this.cpu = builder.cpu; this.ram = builder.ram; this.storage = builder.storage; this.gpu = builder.gpu; this.screen = builder.screen; }
public static class Builder { private String cpu; private String ram; private String storage; private String gpu; private String screen;
public Builder cpu(String cpu) { this.cpu = cpu; return this; }
public Builder ram(String ram) { this.ram = ram; return this; }
public Builder storage(String storage) { this.storage = storage; return this; }
public Builder gpu(String gpu) { this.gpu = gpu; return this; }
public Builder screen(String screen) { this.screen = screen; return this; }
public Computer build() { return new Computer(this); } } }
Computer computer = new Computer.Builder() .cpu("Intel i9") .ram("32GB") .storage("1TB SSD") .gpu("RTX 4090") .screen("4K") .build();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ┌──────────────────────────────────────────────────────────────────┐ │ 建造者模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 适用场景: │ │ • 构造函数参数过多 │ │ • 需要创建不可变对象 │ │ • 参数之间有依赖关系或需要校验 │ │ │ │ JDK中的应用: │ │ • StringBuilder │ │ • Stream.Builder │ │ • Locale.Builder │ │ │ │ 第三方库: │ │ • Lombok的@Builder注解 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
原型模式(Prototype)
通过复制现有对象来创建新对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Prototype implements Cloneable { private String name; private List<String> items;
public Prototype(String name) { this.name = name; this.items = new ArrayList<>(); }
@Override public Prototype clone() { try { return (Prototype) super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } }
public Prototype deepClone() { Prototype clone = new Prototype(this.name); clone.items = new ArrayList<>(this.items); return clone; } }
|
结构型模式
适配器模式(Adapter)
将一个类的接口转换成客户期望的另一个接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public interface MediaPlayer { void play(String filename); }
public class VlcPlayer { public void playVlc(String filename) { System.out.println("Playing VLC: " + filename); } }
public class Mp4Player { public void playMp4(String filename) { System.out.println("Playing MP4: " + filename); } }
public class MediaAdapter implements MediaPlayer { private VlcPlayer vlcPlayer; private Mp4Player mp4Player;
public MediaAdapter(String audioType) { if (audioType.equalsIgnoreCase("vlc")) { vlcPlayer = new VlcPlayer(); } else if (audioType.equalsIgnoreCase("mp4")) { mp4Player = new Mp4Player(); } }
@Override public void play(String filename) { if (vlcPlayer != null) { vlcPlayer.playVlc(filename); } else if (mp4Player != null) { mp4Player.playMp4(filename); } } }
MediaPlayer player = new MediaAdapter("vlc"); player.play("movie.vlc");
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ┌──────────────────────────────────────────────────────────────────┐ │ 适配器模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Client │───────▶│ Target │◀───────│ Adapter │ │ │ └──────────┘ │(interface)│ └────┬─────┘ │ │ └──────────┘ │ │ │ │ 持有 │ │ ▼ │ │ ┌──────────┐ │ │ │ Adaptee │ │ │ │(被适配者) │ │ │ └──────────┘ │ │ │ │ JDK中的应用: │ │ • InputStreamReader(InputStream → Reader) │ │ • Arrays.asList()(数组 → List) │ │ • Collections.enumeration() │ │ │ └──────────────────────────────────────────────────────────────────┘
|
装饰器模式(Decorator)
动态地给对象添加额外的职责。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| public interface Coffee { String getDescription(); double getCost(); }
public class SimpleCoffee implements Coffee { @Override public String getDescription() { return "普通咖啡"; }
@Override public double getCost() { return 10.0; } }
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() + " + 牛奶"; }
@Override public double getCost() { return coffee.getCost() + 3.0; } }
public class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); }
@Override public String getDescription() { return coffee.getDescription() + " + 糖"; }
@Override public double getCost() { return coffee.getCost() + 1.0; } }
Coffee coffee = new SimpleCoffee(); coffee = new MilkDecorator(coffee); coffee = new SugarDecorator(coffee); System.out.println(coffee.getDescription()); System.out.println(coffee.getCost());
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ┌──────────────────────────────────────────────────────────────────┐ │ 装饰器模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ │ │ │ Component │ │ │ │ (interface) │ │ │ └────────┬────────┘ │ │ │ │ │ ┌────────────┴────────────┐ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ConcreteComponent│ │ Decorator │ │ │ │ (SimpleCoffee) │ │ (abstract) │ │ │ └─────────────────┘ └────────┬────────┘ │ │ │ │ │ ┌──────────┴──────────┐ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ MilkDecorator │ │ SugarDecorator │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ JDK中的应用: │ │ • Java I/O流(BufferedInputStream包装InputStream) │ │ • Collections.synchronizedList() │ │ • Collections.unmodifiableList() │ │ │ └──────────────────────────────────────────────────────────────────┘
|
代理模式(Proxy)
为其他对象提供一种代理以控制对这个对象的访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public interface Image { void display(); }
public class RealImage implements Image { private String filename;
public RealImage(String filename) { this.filename = filename; loadFromDisk(); }
private void loadFromDisk() { System.out.println("Loading image: " + filename); }
@Override public void display() { System.out.println("Displaying: " + filename); } }
public class ProxyImage implements Image { private String filename; private RealImage realImage;
public ProxyImage(String filename) { this.filename = filename; }
@Override public void display() { if (realImage == null) { realImage = new RealImage(filename); } realImage.display(); } }
Image image = new ProxyImage("photo.jpg");
image.display(); image.display();
|
JDK动态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public interface UserService { void save(String name); }
public class UserServiceImpl implements UserService { @Override public void save(String name) { System.out.println("保存用户: " + name); } }
public class LoggingHandler implements InvocationHandler { private Object target;
public LoggingHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法调用前: " + method.getName()); Object result = method.invoke(target, args); System.out.println("方法调用后: " + method.getName()); return result; } }
UserService userService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new LoggingHandler(userService) ); proxy.save("张三");
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| ┌──────────────────────────────────────────────────────────────────┐ │ 代理模式类型 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 静态代理 │ │ • 编译期确定代理类 │ │ • 每个被代理类需要一个代理类 │ │ │ │ JDK动态代理 │ │ • 运行时生成代理类 │ │ • 被代理类必须实现接口 │ │ • 使用Proxy.newProxyInstance() │ │ │ │ CGLIB代理 │ │ • 运行时生成代理类 │ │ • 通过继承实现,无需接口 │ │ • 不能代理final类和方法 │ │ │ │ 应用场景: │ │ • AOP(面向切面编程) │ │ • 远程代理(RPC) │ │ • 延迟加载 │ │ • 访问控制 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
外观模式(Facade)
为子系统提供一个统一的高层接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class CPU { public void start() { System.out.println("CPU启动"); } public void shutdown() { System.out.println("CPU关闭"); } }
public class Memory { public void load() { System.out.println("内存加载"); } public void clear() { System.out.println("内存清理"); } }
public class HardDrive { public void read() { System.out.println("硬盘读取"); } public void write() { System.out.println("硬盘写入"); } }
public class ComputerFacade { private CPU cpu; private Memory memory; private HardDrive hardDrive;
public ComputerFacade() { this.cpu = new CPU(); this.memory = new Memory(); this.hardDrive = new HardDrive(); }
public void start() { cpu.start(); memory.load(); hardDrive.read(); System.out.println("电脑启动完成"); }
public void shutdown() { hardDrive.write(); memory.clear(); cpu.shutdown(); System.out.println("电脑关机完成"); } }
ComputerFacade computer = new ComputerFacade(); computer.start(); computer.shutdown();
|
组合模式(Composite)
将对象组合成树形结构,使客户端统一处理单个对象和组合对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| public interface FileSystemComponent { void display(int indent); long getSize(); }
public class File implements FileSystemComponent { private String name; private long size;
public File(String name, long size) { this.name = name; this.size = size; }
@Override public void display(int indent) { System.out.println(" ".repeat(indent) + "📄 " + name + " (" + size + "KB)"); }
@Override public long getSize() { return size; } }
public class Directory implements FileSystemComponent { private String name; private List<FileSystemComponent> children = new ArrayList<>();
public Directory(String name) { this.name = name; }
public void add(FileSystemComponent component) { children.add(component); }
public void remove(FileSystemComponent component) { children.remove(component); }
@Override public void display(int indent) { System.out.println(" ".repeat(indent) + "📁 " + name); for (FileSystemComponent child : children) { child.display(indent + 2); } }
@Override public long getSize() { return children.stream() .mapToLong(FileSystemComponent::getSize) .sum(); } }
Directory root = new Directory("root"); Directory docs = new Directory("documents"); docs.add(new File("resume.pdf", 100)); docs.add(new File("report.docx", 200)); root.add(docs); root.add(new File("readme.txt", 10)); root.display(0);
|
行为型模式
策略模式(Strategy)
定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| public interface PaymentStrategy { void pay(double amount); }
public class CreditCardPayment implements PaymentStrategy { private String cardNumber;
public CreditCardPayment(String cardNumber) { this.cardNumber = cardNumber; }
@Override public void pay(double amount) { System.out.println("信用卡支付: " + amount + "元,卡号: " + cardNumber); } }
public class AlipayPayment implements PaymentStrategy { private String account;
public AlipayPayment(String account) { this.account = account; }
@Override public void pay(double amount) { System.out.println("支付宝支付: " + amount + "元,账号: " + account); } }
public class WeChatPayment implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("微信支付: " + amount + "元"); } }
public class ShoppingCart { private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) { this.paymentStrategy = strategy; }
public void checkout(double amount) { paymentStrategy.pay(amount); } }
ShoppingCart cart = new ShoppingCart(); cart.setPaymentStrategy(new AlipayPayment("user@example.com")); cart.checkout(100.0);
cart.setPaymentStrategy(new WeChatPayment()); cart.checkout(200.0);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ┌──────────────────────────────────────────────────────────────────┐ │ 策略模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌─────────────────┐ │ │ │ Context │────────▶│ Strategy │ │ │ │ │ │ (interface) │ │ │ └──────────┘ └────────┬────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │StrategyA │ │StrategyB │ │StrategyC │ │ │ │(CreditCard) │ │(Alipay) │ │(WeChat) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ vs if-else: │ │ • 策略模式符合开闭原则 │ │ • 新增策略无需修改现有代码 │ │ • 算法可以独立变化 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
观察者模式(Observer)
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public interface Observer { void update(String message); }
public interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); }
public class NewsPublisher implements Subject { private List<Observer> observers = new ArrayList<>(); private String news;
@Override public void registerObserver(Observer observer) { observers.add(observer); }
@Override public void removeObserver(Observer observer) { observers.remove(observer); }
@Override public void notifyObservers() { for (Observer observer : observers) { observer.update(news); } }
public void publishNews(String news) { this.news = news; notifyObservers(); } }
public class EmailSubscriber implements Observer { private String email;
public EmailSubscriber(String email) { this.email = email; }
@Override public void update(String message) { System.out.println("发送邮件到 " + email + ": " + message); } }
public class AppSubscriber implements Observer { private String userId;
public AppSubscriber(String userId) { this.userId = userId; }
@Override public void update(String message) { System.out.println("推送通知给用户 " + userId + ": " + message); } }
NewsPublisher publisher = new NewsPublisher(); publisher.registerObserver(new EmailSubscriber("user@example.com")); publisher.registerObserver(new AppSubscriber("12345")); publisher.publishNews("重大新闻发布!");
|
Java内置观察者(JDK 9后已废弃)
1 2 3 4 5
|
public class NewsPublisher implements Flow.Publisher<String> { }
|
模板方法模式(Template Method)
定义算法骨架,将某些步骤延迟到子类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| public abstract class DataProcessor {
public final void process() { readData(); processData(); writeData(); if (needsNotification()) { sendNotification(); } }
protected abstract void readData(); protected abstract void processData();
protected void writeData() { System.out.println("写入数据到默认位置"); }
protected boolean needsNotification() { return false; }
protected void sendNotification() { System.out.println("发送通知"); } }
public class CSVDataProcessor extends DataProcessor { @Override protected void readData() { System.out.println("读取CSV文件"); }
@Override protected void processData() { System.out.println("处理CSV数据"); } }
public class DatabaseDataProcessor extends DataProcessor { @Override protected void readData() { System.out.println("从数据库读取"); }
@Override protected void processData() { System.out.println("处理数据库数据"); }
@Override protected boolean needsNotification() { return true; } }
DataProcessor processor = new DatabaseDataProcessor(); processor.process();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| ┌──────────────────────────────────────────────────────────────────┐ │ 模板方法模式 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌────────────────────────────────────────────────┐ │ │ │ AbstractClass │ │ │ │────────────────────────────────────────────────│ │ │ │ + templateMethod() { // 模板方法 │ │ │ │ step1(); │ │ │ │ step2(); │ │ │ │ if (hook()) step3(); │ │ │ │ } │ │ │ │ # step1() // 抽象方法 │ │ │ │ # step2() // 抽象方法 │ │ │ │ # step3() // 具体方法 │ │ │ │ # hook(): boolean // 钩子方法 │ │ │ └───────────────────────┬────────────────────────┘ │ │ │ │ │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ ConcreteClassA │ │ ConcreteClassB │ │ │ │ step1() {...} │ │ step1() {...} │ │ │ │ step2() {...} │ │ step2() {...} │ │ │ └─────────────────┘ │ hook() {true} │ │ │ └─────────────────┘ │ │ │ │ JDK中的应用: │ │ • InputStream.read() │ │ • AbstractList.get() │ │ • HttpServlet.service() │ │ │ └──────────────────────────────────────────────────────────────────┘
|
责任链模式(Chain of Responsibility)
使多个对象都有机会处理请求,将这些对象连成一条链。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public abstract class Handler { protected Handler nextHandler;
public void setNext(Handler handler) { this.nextHandler = handler; }
public abstract void handle(Request request); }
public class Request { private String type; private double amount;
public Request(String type, double amount) { this.type = type; this.amount = amount; }
public String getType() { return type; } public double getAmount() { return amount; } }
public class ManagerHandler extends Handler { @Override public void handle(Request request) { if (request.getAmount() <= 1000) { System.out.println("经理批准: " + request.getAmount()); } else if (nextHandler != null) { nextHandler.handle(request); } } }
public class DirectorHandler extends Handler { @Override public void handle(Request request) { if (request.getAmount() <= 5000) { System.out.println("总监批准: " + request.getAmount()); } else if (nextHandler != null) { nextHandler.handle(request); } } }
public class CEOHandler extends Handler { @Override public void handle(Request request) { if (request.getAmount() <= 50000) { System.out.println("CEO批准: " + request.getAmount()); } else { System.out.println("金额太大,需要董事会审批"); } } }
Handler manager = new ManagerHandler(); Handler director = new DirectorHandler(); Handler ceo = new CEOHandler();
manager.setNext(director); director.setNext(ceo);
manager.handle(new Request("报销", 500)); manager.handle(new Request("采购", 3000)); manager.handle(new Request("投资", 20000));
|
状态模式(State)
允许对象在内部状态改变时改变它的行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| public interface State { void insertCoin(VendingMachine machine); void pressButton(VendingMachine machine); void dispense(VendingMachine machine); }
public class NoCoinState implements State { @Override public void insertCoin(VendingMachine machine) { System.out.println("投币成功"); machine.setState(new HasCoinState()); }
@Override public void pressButton(VendingMachine machine) { System.out.println("请先投币"); }
@Override public void dispense(VendingMachine machine) { System.out.println("请先投币"); } }
public class HasCoinState implements State { @Override public void insertCoin(VendingMachine machine) { System.out.println("已有硬币,无需再投"); }
@Override public void pressButton(VendingMachine machine) { System.out.println("正在出货..."); machine.setState(new DispensingState()); }
@Override public void dispense(VendingMachine machine) { System.out.println("请按按钮"); } }
public class DispensingState implements State { @Override public void insertCoin(VendingMachine machine) { System.out.println("正在出货,请稍等"); }
@Override public void pressButton(VendingMachine machine) { System.out.println("正在出货,请稍等"); }
@Override public void dispense(VendingMachine machine) { System.out.println("商品已送出"); machine.setState(new NoCoinState()); } }
public class VendingMachine { private State state;
public VendingMachine() { this.state = new NoCoinState(); }
public void setState(State state) { this.state = state; }
public void insertCoin() { state.insertCoin(this); }
public void pressButton() { state.pressButton(this); state.dispense(this); } }
VendingMachine machine = new VendingMachine(); machine.pressButton(); machine.insertCoin(); machine.pressButton();
|
命令模式(Command)
将请求封装成对象,使你可以用不同的请求参数化客户端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| public interface Command { void execute(); void undo(); }
public class Light { public void on() { System.out.println("灯打开"); }
public void off() { System.out.println("灯关闭"); } }
public class LightOnCommand implements Command { private Light light;
public LightOnCommand(Light light) { this.light = light; }
@Override public void execute() { light.on(); }
@Override public void undo() { light.off(); } }
public class LightOffCommand implements Command { private Light light;
public LightOffCommand(Light light) { this.light = light; }
@Override public void execute() { light.off(); }
@Override public void undo() { light.on(); } }
public class RemoteControl { private Command command; private Stack<Command> history = new Stack<>();
public void setCommand(Command command) { this.command = command; }
public void pressButton() { command.execute(); history.push(command); }
public void pressUndo() { if (!history.isEmpty()) { history.pop().undo(); } } }
Light light = new Light(); RemoteControl remote = new RemoteControl();
remote.setCommand(new LightOnCommand(light)); remote.pressButton(); remote.pressUndo();
|
迭代器模式(Iterator)
提供一种方法顺序访问集合元素,而不暴露其内部表示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public interface Iterator<T> { boolean hasNext(); T next(); }
public interface Container<T> { Iterator<T> createIterator(); }
public class BookCollection implements Container<String> { private String[] books;
public BookCollection(String[] books) { this.books = books; }
@Override public Iterator<String> createIterator() { return new BookIterator(); }
private class BookIterator implements Iterator<String> { private int index = 0;
@Override public boolean hasNext() { return index < books.length; }
@Override public String next() { return books[index++]; } } }
BookCollection collection = new BookCollection( new String[]{"Java编程", "设计模式", "数据结构"} ); Iterator<String> iterator = collection.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
|
设计模式在Java中的应用
JDK中的设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| ┌──────────────────────────────────────────────────────────────────┐ │ JDK中的设计模式应用 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 单例模式 │ │ • Runtime.getRuntime() │ │ • Desktop.getDesktop() │ │ │ │ 工厂模式 │ │ • Calendar.getInstance() │ │ • NumberFormat.getInstance() │ │ • Charset.forName() │ │ │ │ 建造者模式 │ │ • StringBuilder │ │ • Stream.Builder │ │ • Locale.Builder │ │ │ │ 适配器模式 │ │ • InputStreamReader / OutputStreamWriter │ │ • Arrays.asList() │ │ │ │ 装饰器模式 │ │ • BufferedInputStream / BufferedOutputStream │ │ • Collections.synchronizedList() │ │ • Collections.unmodifiableList() │ │ │ │ 代理模式 │ │ • java.lang.reflect.Proxy │ │ • RMI │ │ │ │ 观察者模式 │ │ • java.util.Observer(已废弃) │ │ • java.util.concurrent.Flow │ │ • PropertyChangeListener │ │ │ │ 策略模式 │ │ • Comparator │ │ • ThreadPoolExecutor的RejectedExecutionHandler │ │ │ │ 模板方法模式 │ │ • InputStream.read() │ │ • AbstractList │ │ • HttpServlet.service() │ │ │ │ 迭代器模式 │ │ • Iterator接口 │ │ • Enumeration │ │ │ └──────────────────────────────────────────────────────────────────┘
|
Spring中的设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| ┌──────────────────────────────────────────────────────────────────┐ │ Spring中的设计模式应用 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 单例模式 │ │ • Bean默认是单例的 │ │ │ │ 工厂模式 │ │ • BeanFactory / ApplicationContext │ │ • FactoryBean │ │ │ │ 代理模式 │ │ • AOP的核心实现 │ │ • JDK动态代理 / CGLIB │ │ │ │ 模板方法模式 │ │ • JdbcTemplate │ │ • RestTemplate │ │ • TransactionTemplate │ │ │ │ 观察者模式 │ │ • ApplicationEvent / ApplicationListener │ │ • @EventListener │ │ │ │ 策略模式 │ │ • Resource接口的多种实现 │ │ • HandlerMapping │ │ │ │ 适配器模式 │ │ • HandlerAdapter │ │ • MessageListenerAdapter │ │ │ │ 装饰器模式 │ │ • BeanWrapper │ │ • HttpServletRequestWrapper │ │ │ │ 责任链模式 │ │ • Filter链 │ │ • Interceptor链 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
设计模式选择指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| ┌──────────────────────────────────────────────────────────────────┐ │ 设计模式选择指南 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 问题场景 推荐模式 │ │ ─────────────────────────────────────────────────────────────── │ │ 需要确保只有一个实例 单例模式 │ │ 创建对象的细节需要隐藏 工厂模式 │ │ 创建相关产品族 抽象工厂 │ │ 分步骤构建复杂对象 建造者模式 │ │ 需要复制现有对象 原型模式 │ │ │ │ 接口不兼容需要转换 适配器模式 │ │ 需要动态添加功能 装饰器模式 │ │ 需要控制对象访问 代理模式 │ │ 简化复杂子系统 外观模式 │ │ 处理树形结构 组合模式 │ │ 分离抽象与实现 桥接模式 │ │ 需要共享大量细粒度对象 享元模式 │ │ │ │ 算法需要灵活切换 策略模式 │ │ 一对多的消息通知 观察者模式 │ │ 定义算法骨架 模板方法 │ │ 对象行为随状态改变 状态模式 │ │ 请求需要多级处理 责任链模式 │ │ 封装请求为对象 命令模式 │ │ 遍历集合元素 迭代器模式 │ │ │ └──────────────────────────────────────────────────────────────────┘
|
总结
设计原则
| 原则 |
核心思想 |
| 单一职责(SRP) |
一个类只做一件事 |
| 开闭原则(OCP) |
对扩展开放,对修改关闭 |
| 里氏替换(LSP) |
子类可以替换父类 |
| 接口隔离(ISP) |
接口要小而专一 |
| 依赖倒置(DIP) |
依赖抽象不依赖实现 |
| 迪米特法则 |
最少知识原则 |
| 合成复用 |
组合优于继承 |
常用设计模式
| 类型 |
模式 |
一句话描述 |
| 创建型 |
单例 |
确保唯一实例 |
| 创建型 |
工厂方法 |
延迟到子类创建对象 |
| 创建型 |
建造者 |
分步构建复杂对象 |
| 结构型 |
适配器 |
转换不兼容接口 |
| 结构型 |
装饰器 |
动态添加功能 |
| 结构型 |
代理 |
控制对象访问 |
| 行为型 |
策略 |
封装可替换算法 |
| 行为型 |
观察者 |
一对多消息通知 |
| 行为型 |
模板方法 |
定义算法骨架 |
| 行为型 |
责任链 |
多级请求处理 |
设计模式不是银弹,应该根据具体场景选择合适的模式。过度设计和不使用设计模式一样有害。最重要的是理解每个模式解决的问题,在合适的场景应用合适的模式。