15种经典设计模式详解:Java实现与最佳实践指南
2025/9/1...大约 8 分钟
15种经典设计模式详解:Java实现与最佳实践指南
设计模式是软件工程中的“武功秘籍”,是前辈们在无数实践中总结出来的解决常见问题的精妙方案。它们能让你的代码更健壮、更灵活、更易于扩展。
一、创建型模式 (Creational Patterns)
这类模式的核心是如何创建对象,它们将对象的创建过程和使用过程分离开,让你的系统在创建对象时更具弹性。
1. Singleton (单例模式)
- 目的: 确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点。
- 如何实现: 私有化构造函数,并通过一个公共静态方法来获取唯一的实例。
public class ConfigurationManager {
private static ConfigurationManager instance;
private ConfigurationManager() {}
public static ConfigurationManager getInstance() {
if (instance == null) {
instance = new ConfigurationManager();
}
return instance;
}
}
2. Factory Method (工厂方法模式)
- 目的: 定义一个创建对象的接口,但让子类决定实例化哪一个类。
- 如何实现: 抽象工厂接口定义创建方法,每个具体子类工厂负责创建一种具体产品。
interface Car { void drive(); }
class Audi implements Car { public void drive() { System.out.println("Driving Audi."); } }
interface CarFactory { Car createCar(); }
class AudiFactory implements CarFactory {
public Car createCar() { return new Audi(); }
}
3. Abstract Factory (抽象工厂模式)
- 目的: 创建一组相关或相互依赖的对象,无需指定它们的具体类。
- 如何实现: 定义一个抽象工厂接口,其中包含多个创建不同类型产品的方法。
// 抽象产品
interface Button { void render(); }
interface Checkbox { void render(); }
// 具体产品
class WinButton implements Button { public void render() { System.out.println("Rendering a Windows Button."); } }
class MacButton implements Button { public void render() { System.out.println("Rendering a Mac Button."); } }
// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂
class WindowsFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public Checkbox createCheckbox() { return new WinCheckbox(); }
}
4. Builder (建造者模式)
- 目的: 将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
- 如何实现: 定义一个建造者接口,包含分步构建方法,以及一个获取最终产品的方法。
class Computer {
private String cpu;
private String ram;
private String storage;
// ...getters and setters...
}
interface ComputerBuilder {
void buildCPU();
void buildRAM();
void buildStorage();
Computer getResult();
}
class GamingComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
public void buildCPU() { computer.setCpu("Intel Core i9"); }
public void buildRAM() { computer.setRam("32GB DDR5"); }
public void buildStorage() { computer.setStorage("1TB SSD"); }
public Computer getResult() { return computer; }
}
二、结构型模式 (Structural Patterns)
这类模式关注如何组合类和对象,形成更大的结构,使它们协同工作。
5. Adapter (适配器模式)
- 目的: 让接口不兼容的对象协同工作。
- 如何实现: 创建一个“适配器”类,它实现了你想要的接口,并在内部持有了不兼容的对象。
interface MediaPlayer { void play(String audioType, String fileName); }
class AdvancedMediaPlayer { public void playMp4(String fileName) { System.out.println("Playing mp4 file: " + fileName); } }
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedPlayer;
public MediaAdapter() { this.advancedPlayer = new AdvancedMediaPlayer(); }
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp4")) {
advancedPlayer.playMp4(fileName);
}
}
}
6. Facade (外观模式)
- 目的: 为复杂的子系统提供一个简化的统一接口。
- 如何实现: 创建一个外观类,它包含对子系统中多个类的引用,并提供一个简单的方法来调用这些子系统。
class Amplifier { public void turnOn() { System.out.println("Amplifier on."); } }
class DvdPlayer { public void turnOn() { System.out.println("DVD Player on."); } }
class Lights { public void dim() { System.out.println("Lights dimmed."); } }
class HomeTheaterFacade {
Amplifier amp;
DvdPlayer dvd;
Lights lights;
// constructor...
public void watchMovie() {
lights.dim();
amp.turnOn();
dvd.turnOn();
System.out.println("Movie is playing...");
}
}
7. Decorator (装饰器模式)
- 目的: 动态地给对象添加新功能,而不改变其结构。
- 如何实现: 创建一个装饰器抽象类,它继承自被装饰者的父类,并持有一个被装饰者的引用。具体装饰器子类则负责添加新功能。
interface Coffee { double getCost(); String getDescription(); }
class SimpleCoffee implements Coffee {
public double getCost() { return 10; }
public String getDescription() { return "Simple coffee"; }
}
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; }
public double getCost() { return decoratedCoffee.getCost(); }
public String getDescription() { return decoratedCoffee.getDescription(); }
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) { super(coffee); }
public double getCost() { return super.getCost() + 2.0; }
public String getDescription() { return super.getDescription() + ", with milk"; }
}
8. Composite (组合模式)
- 目的: 将对象组合成树形结构以表示“部分-整体”的层次结构。
- 如何实现: 定义一个组件接口,它可以是叶子节点(简单对象)或容器节点(包含其他组件)。
import java.util.ArrayList;
import java.util.List;
interface Component { void showInfo(); }
class File implements Component {
private String name;
public File(String name) { this.name = name; }
public void showInfo() { System.out.println("File: " + name); }
}
class Directory implements Component {
private String name;
private List<Component> components = new ArrayList<>();
public Directory(String name) { this.name = name; }
public void add(Component c) { components.add(c); }
public void showInfo() {
System.out.println("Directory: " + name);
for (Component c : components) {
c.showInfo();
}
}
}
9. Proxy (代理模式)
- 目的: 为另一个对象提供一个占位符或代理来控制对它的访问。
- 如何实现: 代理类和被代理类实现同一个接口,代理类持有一个被代理类的引用,并控制对它的调用。
interface Image { void display(); }
class RealImage implements Image {
private String filename;
public RealImage(String filename) { this.filename = filename; loadFromDisk(); }
private void loadFromDisk() { System.out.println("Loading " + filename); }
public void display() { System.out.println("Displaying " + filename); }
}
class ProxyImage implements Image {
private RealImage realImage;
private String filename;
public ProxyImage(String filename) { this.filename = filename; }
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
三、行为型模式 (Behavioral Patterns)
这类模式关注对象之间的责任分配和算法,描述了对象如何相互通信和协作。
10. Iterator (迭代器模式)
- 目的: 提供一种顺序访问聚合对象中的元素的方法,而无需暴露其内部表示。
- 如何实现: 定义一个迭代器接口,包含
hasNext()
和next()
方法。
import java.util.List;
import java.util.ArrayList;
interface MyIterator { boolean hasNext(); Object next(); }
class BookShelfIterator implements MyIterator {
private List<String> books;
private int index = 0;
public BookShelfIterator(List<String> books) { this.books = books; }
public boolean hasNext() { return index < books.size(); }
public Object next() { return books.get(index++); }
}
11. Observer (观察者模式)
- 目的: 定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖于它的对象都会自动得到通知并更新。
- 如何实现: “被观察者”维护一个“观察者”列表,并在状态改变时遍历列表通知它们。
import java.util.ArrayList;
import java.util.List;
interface Observer { void update(String message); }
interface Subject { void attach(Observer o); void notifyObservers(String message); }
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer o) { observers.add(o); }
public void notifyObservers(String message) {
for (Observer o : observers) {
o.update(message);
}
}
}
12. Strategy (策略模式)
- 目的: 定义一系列算法,将它们封装起来并使它们可以互换。
- 如何实现: 定义一个“策略”接口,每个具体策略类实现一种算法。
interface PaymentStrategy { void pay(double amount); }
class AlipayStrategy implements PaymentStrategy {
public void pay(double amount) { System.out.println("Paying " + amount + " with Alipay."); }
}
class PaymentContext {
private PaymentStrategy strategy;
public void setPaymentStrategy(PaymentStrategy s) { this.strategy = s; }
public void executePayment(double amount) { strategy.pay(amount); }
}
13. Command (命令模式)
- 目的: 将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化。
- 如何实现: 定义一个命令接口,包含一个
execute()
方法。具体命令类实现该接口,并持有接收者对象。
// 命令接口
interface Command { void execute(); }
// 接收者:真正执行操作的对象
class Light {
public void turnOn() { System.out.println("Light is on."); }
public void turnOff() { System.out.println("Light is off."); }
}
// 具体命令:封装请求
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.turnOn(); }
}
14. State (状态模式)
- 目的: 允许一个对象在其内部状态改变时改变它的行为。
- 如何实现: 将对象的行为封装到不同的状态类中,并让对象持有一个当前状态的引用。
interface VendingMachineState { void selectProduct(); void dispenseProduct(); }
class NoProductState implements VendingMachineState {
public void selectProduct() { System.out.println("Product selected."); }
public void dispenseProduct() { System.out.println("No product to dispense."); }
}
class HasProductState implements VendingMachineState {
public void selectProduct() { System.out.println("Product already selected."); }
public void dispenseProduct() { System.out.println("Dispensing product..."); }
}
15. Template Method (模板方法模式)
- 目的: 定义一个操作中的算法骨架,而将一些步骤延迟到子类中。
- 如何实现: 在抽象父类中定义一个模板方法,它调用一些抽象的“钩子”方法,由子类来实现这些钩子。
abstract class HouseBuilder {
public final void buildHouse() {
buildFoundation();
buildWalls();
buildRoof();
}
protected abstract void buildFoundation();
protected abstract void buildWalls();
protected abstract void buildRoof();
}
class WoodHouseBuilder extends HouseBuilder {
protected void buildFoundation() { System.out.println("Building wooden foundation."); }
protected void buildWalls() { System.out.println("Building wooden walls."); }
protected void buildRoof() { System.out.println("Building wooden roof."); }
}