软件开发的23种设计模式详解
设计模式概述
设计模式是软件开发人员在解决特定问题时总结出的可复用解决方案 ,它们提供了经过验证的最佳实践,能够显著提高代码的复用性、可维护性和灵活性。GOF23(Gang of Four 23种设计模式)是最经典的设计模式集合,由四位软件工程专家在《设计模式:可复用面向对象软件的基础》一书中提出。
设计模式基于五大基本原则:单一职责原则 (一个类只负责一个功能领域)、里氏替换原则 (子类可以扩展父类功能但不能改变)、依赖倒置原则 (依赖于抽象而不是具体实现)、接口隔离原则 (使用多个专门的接口)和迪米特法则(减少对象间的耦合)。
设计模式分类体系
三大类别对比分析
| 类别 | 核心关注点 | 主要目的 | 包含模式数量 |
|---|---|---|---|
| 创建型模式 | 对象创建机制 | 封装对象的创建过程,降低系统耦合度 | 5种 |
| 结构型模式 | 类和对象组合 | 通过组合形成更大的结构,提高系统灵活性 | 7种 |
| 行为型模式 | 对象间通信 | 优化对象间的职责分配和算法封装 | 11种 |
创建型模式详解
1. 单例模式(Singleton Pattern)
核心思想:确保一个类只有一个实例,并提供全局访问点。
java
public class Singleton {
private static Singleton instance;
// 私有构造函数防止外部实例化
private Singleton() {}
// 全局访问点
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
应用场景:数据库连接池、日志管理器、配置对象等需要全局唯一实例的场景。
2. 工厂方法模式(Factory Method Pattern)
核心思想:定义一个创建对象的接口,让子类决定实例化哪一个类。
java
// 抽象产品
interface Product {
void use();
}
// 具体产品
class ConcreteProduct implements Product {
public void use() {
System.out.println("使用具体产品");
}
}
// 抽象工厂
interface Factory {
Product createProduct();
}
// 具体工厂
class ConcreteFactory implements Factory {
public Product createProduct() {
return new ConcreteProduct();
}
}
3. 抽象工厂模式(Abstract Factory Pattern)
核心思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
java
// 抽象产品A
interface Button {
void render();
}
// 抽象产品B
interface Checkbox {
void check();
}
// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Windows系列产品工厂
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
4. 建造者模式(Builder Pattern)
核心思想:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
java
class Computer {
private String cpu;
private String memory;
private String disk;
// 建造者
public static class Builder {
private String cpu;
private String memory;
private String disk;
public Builder setCpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMemory(String memory) {
this.memory = memory;
return this;
}
public Builder setDisk(String disk) {
this.disk = disk;
return this;
}
public Computer build() {
return new Computer(this);
}
}
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
this.disk = builder.disk;
}
}
5. 原型模式(Prototype Pattern)
核心思想:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
java
interface Prototype extends Cloneable {
Prototype clone();
}
class ConcretePrototype implements Prototype {
private String field;
public ConcretePrototype(String field) {
this.field = field;
}
public Prototype clone() {
try {
return (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败");
}
}
}
结构型模式详解
6. 适配器模式(Adapter Pattern)
核心思想:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
java
// 目标接口
interface Target {
void request();
}
// 需要适配的类
class Adaptee {
public void specificRequest() {
System.out.println("特殊请求");
}
}
// 适配器
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest(); // 适配调用
}
}
7. 桥接模式(Bridge Pattern)
核心思想:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
java
// 实现接口
interface Implementor {
void operationImpl();
}
// 抽象类
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 扩展抽象类
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void operation() {
implementor.operationImpl();
}
}
8. 组合模式(Composite Pattern)
核心思想:将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
java
// 组件接口
interface Component {
void operation();
void add(Component component);
void remove(Component component);
Component getChild(int index);
}
// 叶子节点
class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
public void operation() {
System.out.println("叶子节点: " + name);
}
public void add(Component component) {
throw new UnsupportedOperationException();
}
public void remove(Component component) {
throw new UnsupportedOperationException();
}
public Component getChild(int index) {
throw new UnsupportedOperationException();
}
}
// 复合节点
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void operation() {
for (Component child : children) {
child.operation();
}
}
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
public Component getChild(int index) {
return children.get(index);
}
}
9. 装饰器模式(Decorator Pattern)
核心思想:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
java
// 组件接口
interface Component {
void operation();
}
// 具体组件
class ConcreteComponent implements Component {
public void operation() {
System.out.println("具体组件的操作");
}
}
// 装饰器抽象类
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
// 具体装饰器
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("装饰器添加的行为");
}
}
10. 外观模式(Facade Pattern)
核心思想:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
java
// 子系统A
class SubSystemA {
public void operationA() {
System.out.println("子系统A操作");
}
}
// 子系统B
class SubSystemB {
public void operationB() {
System.out.println("子系统B操作");
}
}
// 外观类
class Facade {
private SubSystemA systemA;
private SubSystemB systemB;
public Facade() {
systemA = new SubSystemA();
systemB = new SubSystemB();
}
public void operation() {
systemA.operationA();
systemB.operationB();
}
}
11. 享元模式(Flyweight Pattern)
核心思想:运用共享技术有效地支持大量细粒度的对象。
java
// 享元接口
interface Flyweight {
void operation(String extrinsicState);
}
// 具体享元
class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(String extrinsicState) {
System.out.println("内部状态: " + intrinsicState + ", 外部状态: " + extrinsicState);
}
}
// 享元工厂
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new ConcreteFlyweight(key));
}
return flyweights.get(key);
}
}
12. 代理模式(Proxy Pattern)
核心思想:为其他对象提供一种代理以控制对这个对象的访问。
java
// 主题接口
interface Subject {
void request();
}
// 真实主题
class RealSubject implements Subject {
public void request() {
System.out.println("真实主题的请求");
}
}
// 代理类
class Proxy implements Subject {
private RealSubject realSubject;
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.request();
postRequest();
}
private void preRequest() {
System.out.println("代理前处理");
}
private void postRequest() {
System.out.println("代理后处理");
}
}
行为型模式详解
13. 责任链模式(Chain of Responsibility Pattern)
核心思想:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
java
// 处理器抽象类
abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
// 具体处理器A
class ConcreteHandlerA extends Handler {
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理器A处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理器B
class ConcreteHandlerB extends Handler {
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理器B处理请求: " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
14. 命令模式(Command Pattern)
核心思想:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
java
// 命令接口
interface Command {
void execute();
void undo();
}
// 具体命令
class ConcreteCommand implements Command {
private Receiver receiver;
private String state;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
state = receiver.getState();
receiver.action();
}
public void undo() {
receiver.setState(state);
}
}
// 接收者
class Receiver {
private String state;
public void action() {
System.out.println("执行操作");
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
15. 解释器模式(Interpreter Pattern)
核心思想:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
java
// 抽象表达式
interface Expression {
boolean interpret(String context);
}
// 终结符表达式
class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
public boolean interpret(String context) {
return context.contains(data);
}
}
// 非终结符表达式
class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
16. 迭代器模式(Iterator Pattern)
核心思想:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
java
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 聚合接口
interface Aggregate {
Iterator createIterator();
}
// 具体迭代器
class ConcreteIterator implements Iterator {
private List<Object> items;
private int position = 0;
public ConcreteIterator(List<Object> items) {
this.items = items;
}
public boolean hasNext() {
return position < items.size();
}
public Object next() {
return items.get(position++);
}
}
// 具体聚合
class ConcreteAggregate implements Aggregate {
private List<Object> items = new ArrayList<>();
public void add(Object item) {
items.add(item);
}
public Iterator createIterator() {
return new ConcreteIterator(items);
}
}
17. 中介者模式(Mediator Pattern)
核心思想:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
java
// 中介者接口
interface Mediator {
void notify(Component sender, String event);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private Component componentA;
private Component componentB;
public void setComponentA(Component componentA) {
this.componentA = componentA;
}
public void setComponentB(Component componentB) {
this.componentB = componentB;
}
public void notify(Component sender, String event) {
if (sender == componentA && "A事件".equals(event)) {
componentB.react();
} else if (sender == componentB && "B事件".equals(event)) {
componentA.react();
}
}
}
// 组件基类
abstract class Component {
protected Mediator mediator;
public Component(Mediator mediator) {
this.mediator = mediator;
}
public abstract void react();
}
18. 备忘录模式(Memento Pattern)
核心思想:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
java
// 备忘录
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 原发器
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento createMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
state = memento.getState();
}
}
// 管理者
class Caretaker {
private Memento memento;
public void setMemento(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
}
19. 观察者模式(Observer Pattern)
核心思想:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
java
// 观察者接口
interface Observer {
void update(String message);
}
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
// 具体观察者
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + " 收到更新: " + message);
}
}
20. 状态模式(State Pattern)
核心思想:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
java
// 状态接口
interface State {
void handle(Context context);
}
// 具体状态A
class ConcreteStateA implements State {
public void handle(Context context) {
System.out.println("当前状态A");
context.setState(new ConcreteStateB());
}
}
// 具体状态B
class ConcreteStateB implements State {
public void handle(Context context) {
System.out.println("当前状态B");
context.setState(new ConcreteStateA());
}
}
// 上下文
class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
21. 策略模式(Strategy Pattern)
核心思想:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法可独立于使用它的客户而变化。
java
// 策略接口
interface Strategy {
int execute(int a, int b);
}
// 具体策略:加法
class AddStrategy implements Strategy {
public int execute(int a, int b) {
return a + b;
}
}
// 具体策略:乘法
class MultiplyStrategy implements Strategy {
public int execute(int a, int b) {
return a * b;
}
}
// 上下文
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
22. 模板方法模式(Template Method Pattern)
核心思想:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
java
// 抽象类
abstract class AbstractClass {
// 模板方法
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
concreteOperation();
}
// 抽象方法,由子类实现
protected abstract void primitiveOperation1();
protected abstract void primitiveOperation2();
// 具体方法
private void concreteOperation() {
System.out.println("具体操作");
}
}
// 具体子类
class ConcreteClass extends AbstractClass {
protected void primitiveOperation1() {
System.out.println("具体操作1");
}
protected void primitiveOperation2() {
System.out.println("具体操作2");
}
}
23. 访问者模式(Visitor Pattern)
核心思想:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
java
// 访问者接口
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素A
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA() {
System.out.println("元素A的操作");
}
}
// 具体元素B
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB() {
System.out.println("元素B的操作");
}
}
// 具体访问者
class ConcreteVisitor implements Visitor {
public void visit(ConcreteElementA element) {
element.operationA();
}
public void visit(ConcreteElementB element) {
element.operationB();
}
}
设计模式应用价值
设计模式在软件开发中具有重要的实践价值 ,它们不仅提供了解决常见问题的标准方案,还促进了代码的可重用性、可扩展性和可维护性 。通过合理运用设计模式,开发人员可以构建更加健壮和灵活的软件系统,有效应对需求变化和技术演进。
在实际项目中,设计模式的选择应该基于具体的问题场景,避免过度设计。理解每种模式的适用场景和优缺点比单纯记忆模式本身更为重要。随着经验的积累,开发人员能够更加准确地判断在何种情况下使用何种设计模式,从而编写出高质量的代码。