设计模式总结详解
设计模式是软件开发中的重要概念,提供了解决常见设计问题的标准方案。本文档系统梳理了设计模式的核心概念、分类体系、实际应用和面试重点,帮助你在实际项目中正确应用设计模式。
通过本章学习,你将掌握:
- 设计模式的基本概念和分类体系
- 23种经典设计模式的原理和应用
- SOLID设计原则和最佳实践
- 设计模式在实际项目中的应用场景
- 面试中常见的设计模式问题
1. 设计模式基本概念
1.1 什么是设计模式?
设计模式是软件开发中常见问题的最佳实践解决方案,它描述了在软件开发过程中不断重复发生的问题,以及该问题的解决方案的核心。
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
1.2 设计模式的作用
| 作用 | 说明 | 示例 |
|---|---|---|
| 代码复用 | 提供可重用的解决方案 | 单例模式确保全局唯一实例 |
| 提高可维护性 | 标准化的代码结构 | 工厂模式统一对象创建 |
| 增强可扩展性 | 支持功能扩展 | 装饰器模式动态添加功能 |
| 降低耦合度 | 减少模块间依赖 | 观察者模式解耦事件处理 |
| 提高可读性 | 清晰的代码意图 | 策略模式明确算法选择 |
1.3 设计模式的核心要素
2. 设计模式分类体系
2.1 按目的分类
设计模式按照其目的可以分为三大类:
创建型模式(Creational Patterns)
结构型模式(Structural Patterns)
行为型模式(Behavioral Patterns)
2.2 按范围分类
类模式 vs 对象模式
| 分类 | 特点 | 示例 |
|---|---|---|
| 类模式 | 处理类与子类之间的关系,通过继承建立 | 模板方法模式、工厂方法模式 |
| 对象模式 | 处理对象间的关系,通过组合建立 | 策略模式、观察者模式、装饰器模式 |
- 类模式:静态关系,编译时确定
- 对象模式:动态关系,运行时确定
- 优先选择对象模式,因为组合比继承更灵活
3. 创建型模式详解
3.1 单例模式(Singleton)
模式定义
确保一个类只有一个实例,并提供一个全局访问点。
实现方式
1public class Singleton {2 // 私有静态实例,使用volatile保证可见性3 private static volatile Singleton instance;4 5 // 私有构造函数,防止外部实例化6 private Singleton() {7 // 防止反射攻击8 if (instance != null) {9 throw new RuntimeException("单例模式不允许创建多个实例");10 }11 }12 13 // 双重检查锁定(Double-Checked Locking)14 public static Singleton getInstance() {15 if (instance == null) {16 synchronized (Singleton.class) {17 if (instance == null) {18 instance = new Singleton();19 }20 }21 }22 return instance;23 }24 25 // 业务方法26 public void doSomething() {27 System.out.println("单例模式执行操作");28 }29}枚举实现(推荐)
1public enum SingletonEnum {2 INSTANCE;3 4 public void doSomething() {5 System.out.println("枚举单例模式执行操作");6 }7}应用场景
- 配置管理器
- 数据库连接池
- 日志记录器
- 缓存管理器
3.2 工厂方法模式(Factory Method)
模式定义
定义一个创建对象的接口,让子类决定实例化哪一个类。
实现示例
1// 抽象产品2public interface Product {3 void operation();4}56// 具体产品A7public class ConcreteProductA implements Product {8 @Override9 public void operation() {10 System.out.println("产品A的操作");11 }12}1314// 具体产品B15public class ConcreteProductB implements Product {16 @Override17 public void operation() {18 System.out.println("产品B的操作");19 }20}2122// 抽象工厂23public abstract class Creator {24 // 工厂方法25 public abstract Product createProduct();26 27 // 模板方法28 public void someOperation() {29 Product product = createProduct();30 product.operation();31 }32}3334// 具体工厂A35public class ConcreteCreatorA extends Creator {36 @Override37 public Product createProduct() {38 return new ConcreteProductA();39 }40}4142// 具体工厂B43public class ConcreteCreatorB extends Creator {44 @Override45 public Product createProduct() {46 return new ConcreteProductB();47 }48}应用场景
- 数据库连接工厂
- 日志记录器工厂
- 图形界面组件工厂
3.3 抽象工厂模式(Abstract Factory)
模式定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
实现示例
1// 抽象产品A2public interface AbstractProductA {3 void operationA();4}56// 抽象产品B7public interface AbstractProductB {8 void operationB();9}1011// 具体产品A112public class ConcreteProductA1 implements AbstractProductA {13 @Override14 public void operationA() {15 System.out.println("产品A1的操作");16 }17}1819// 具体产品B120public class ConcreteProductB1 implements AbstractProductB {21 @Override22 public void operationB() {23 System.out.println("产品B1的操作");24 }25}2627// 抽象工厂28public interface AbstractFactory {29 AbstractProductA createProductA();30 AbstractProductB createProductB();31}3233// 具体工厂134public class ConcreteFactory1 implements AbstractFactory {35 @Override36 public AbstractProductA createProductA() {37 return new ConcreteProductA1();38 }39 40 @Override41 public AbstractProductB createProductB() {42 return new ConcreteProductB1();43 }44}应用场景
- 跨平台UI组件
- 数据库访问层
- 操作系统API
3.4 建造者模式(Builder)
模式定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
实现示例
1// 产品类2public class Computer {3 private String cpu;4 private String memory;5 private String storage;6 private String graphics;7 8 // 私有构造函数9 private Computer() {}10 11 // Getter方法12 public String getCpu() { return cpu; }13 public String getMemory() { return memory; }14 public String getStorage() { return storage; }15 public String getGraphics() { return graphics; }16 17 // 静态内部建造者类18 public static class Builder {19 private Computer computer = new Computer();20 21 public Builder cpu(String cpu) {22 computer.cpu = cpu;23 return this;24 }25 26 public Builder memory(String memory) {27 computer.memory = memory;28 return this;29 }30 31 public Builder storage(String storage) {32 computer.storage = storage;33 return this;34 }35 36 public Builder graphics(String graphics) {37 computer.graphics = graphics;38 return this;39 }40 41 public Computer build() {42 // 参数校验43 if (computer.cpu == null) {44 throw new IllegalArgumentException("CPU不能为空");45 }46 if (computer.memory == null) {47 throw new IllegalArgumentException("内存不能为空");48 }49 return computer;50 }51 }52}使用示例
1public class BuilderExample {2 public static void main(String[] args) {3 Computer computer = new Computer.Builder()4 .cpu("Intel i7")5 .memory("16GB")6 .storage("512GB SSD")7 .graphics("RTX 3080")8 .build();9 10 System.out.println("CPU: " + computer.getCpu());11 System.out.println("内存: " + computer.getMemory());12 }13}应用场景
- 复杂对象构建
- 参数校验
- 不可变对象创建
3.5 原型模式(Prototype)
模式定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
实现示例
1// 原型接口2public interface Prototype extends Cloneable {3 Prototype clone();4 void display();5}67// 具体原型8public class ConcretePrototype implements Prototype {9 private String name;10 private List<String> attributes = new ArrayList<>();11 12 public ConcretePrototype(String name) {13 this.name = name;14 this.attributes.add("属性1");15 this.attributes.add("属性2");16 }17 18 @Override19 public Prototype clone() {20 try {21 ConcretePrototype clone = (ConcretePrototype) super.clone();22 // 深拷贝23 clone.attributes = new ArrayList<>(this.attributes);24 return clone;25 } catch (CloneNotSupportedException e) {26 throw new RuntimeException(e);27 }28 }29 30 @Override31 public void display() {32 System.out.println("原型名称: " + name);33 System.out.println("属性: " + attributes);34 }35 36 public void addAttribute(String attribute) {37 this.attributes.add(attribute);38 }39}应用场景
- 对象克隆
- 配置复制
- 模板复制
- 单例模式:需要全局唯一实例时
- 工厂方法:需要延迟实例化时
- 抽象工厂:需要创建产品族时
- 建造者模式:需要构建复杂对象时
- 原型模式:需要对象克隆时
4. 结构型模式详解
4.1 适配器模式(Adapter)
模式定义
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
类适配器实现
1// 目标接口2public interface Target {3 void request();4}56// 被适配的类7public class Adaptee {8 public void specificRequest() {9 System.out.println("被适配类的特殊请求");10 }11}1213// 类适配器14public class ClassAdapter extends Adaptee implements Target {15 @Override16 public void request() {17 // 调用被适配类的方法18 specificRequest();19 }20}对象适配器实现
1// 对象适配器2public class ObjectAdapter implements Target {3 private Adaptee adaptee;4 5 public ObjectAdapter(Adaptee adaptee) {6 this.adaptee = adaptee;7 }8 9 @Override10 public void request() {11 adaptee.specificRequest();12 }13}应用场景
- 第三方库集成
- 接口兼容性
- 遗留系统改造
4.2 桥接模式(Bridge)
模式定义
将抽象部分与实现部分分离,使它们都可以独立地变化。
实现示例
1// 实现者接口2public interface Implementor {3 void operationImpl();4}56// 具体实现者A7public class ConcreteImplementorA implements Implementor {8 @Override9 public void operationImpl() {10 System.out.println("具体实现者A的操作");11 }12}1314// 具体实现者B15public class ConcreteImplementorB implements Implementor {16 @Override17 public void operationImpl() {18 System.out.println("具体实现者B的操作");19 }20}2122// 抽象类23public abstract class Abstraction {24 protected Implementor implementor;25 26 public Abstraction(Implementor implementor) {27 this.implementor = implementor;28 }29 30 public abstract void operation();31}3233// 精确抽象类34public class RefinedAbstraction extends Abstraction {35 public RefinedAbstraction(Implementor implementor) {36 super(implementor);37 }38 39 @Override40 public void operation() {41 System.out.println("精确抽象类的操作");42 implementor.operationImpl();43 }44}应用场景
- 跨平台开发
- 数据库驱动
- 图形渲染引擎
4.3 组合模式(Composite)
模式定义
将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
实现示例
1// 抽象组件2public abstract class Component {3 protected String name;4 5 public Component(String name) {6 this.name = name;7 }8 9 public abstract void add(Component component);10 public abstract void remove(Component component);11 public abstract void display(int depth);12}1314// 叶子节点15public class Leaf extends Component {16 public Leaf(String name) {17 super(name);18 }19 20 @Override21 public void add(Component component) {22 throw new UnsupportedOperationException("叶子节点不能添加子节点");23 }24 25 @Override26 public void remove(Component component) {27 throw new UnsupportedOperationException("叶子节点不能删除子节点");28 }29 30 @Override31 public void display(int depth) {32 StringBuilder prefix = new StringBuilder();33 for (int i = 0; i < depth; i++) {34 prefix.append(" ");35 }36 System.out.println(prefix + "- " + name);37 }38}3940// 复合节点41public class Composite extends Component {42 private List<Component> children = new ArrayList<>();43 44 public Composite(String name) {45 super(name);46 }47 48 @Override49 public void add(Component component) {50 children.add(component);51 }52 53 @Override54 public void remove(Component component) {55 children.remove(component);56 }57 58 @Override59 public void display(int depth) {60 StringBuilder prefix = new StringBuilder();61 for (int i = 0; i < depth; i++) {62 prefix.append(" ");63 }64 System.out.println(prefix + "+ " + name);65 66 for (Component child : children) {67 child.display(depth + 1);68 }69 }70}应用场景
- 文件系统
- 组织架构
- 菜单系统
4.4 装饰器模式(Decorator)
模式定义
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
实现示例
1// 抽象组件2public interface Component {3 void operation();4}56// 具体组件7public class ConcreteComponent implements Component {8 @Override9 public void operation() {10 System.out.println("具体组件的操作");11 }12}1314// 抽象装饰器15public abstract class Decorator implements Component {16 protected Component component;17 18 public Decorator(Component component) {19 this.component = component;20 }21 22 @Override23 public void operation() {24 component.operation();25 }26}2728// 具体装饰器A29public class ConcreteDecoratorA extends Decorator {30 public ConcreteDecoratorA(Component component) {31 super(component);32 }33 34 @Override35 public void operation() {36 super.operation();37 addedBehavior();38 }39 40 private void addedBehavior() {41 System.out.println("装饰器A添加的行为");42 }43}4445// 具体装饰器B46public class ConcreteDecoratorB extends Decorator {47 public ConcreteDecoratorB(Component component) {48 super(component);49 }50 51 @Override52 public void operation() {53 super.operation();54 addedBehavior();55 }56 57 private void addedBehavior() {58 System.out.println("装饰器B添加的行为");59 }60}使用示例
1public class DecoratorExample {2 public static void main(String[] args) {3 Component component = new ConcreteComponent();4 Component decoratedA = new ConcreteDecoratorA(component);5 Component decoratedB = new ConcreteDecoratorB(decoratedA);6 7 decoratedB.operation();8 // 输出:9 // 具体组件的操作10 // 装饰器A添加的行为11 // 装饰器B添加的行为12 }13}应用场景
- IO流处理
- 缓存装饰
- 权限控制
4.5 外观模式(Facade)
模式定义
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
实现示例
1// 子系统A2public class SubsystemA {3 public void operationA() {4 System.out.println("子系统A的操作");5 }6}78// 子系统B9public class SubsystemB {10 public void operationB() {11 System.out.println("子系统B的操作");12 }13}1415// 子系统C16public class SubsystemC {17 public void operationC() {18 System.out.println("子系统C的操作");19 }20}2122// 外观类23public class Facade {24 private SubsystemA subsystemA;25 private SubsystemB subsystemB;26 private SubsystemC subsystemC;27 28 public Facade() {29 this.subsystemA = new SubsystemA();30 this.subsystemB = new SubsystemB();31 this.subsystemC = new SubsystemC();32 }33 34 public void operation() {35 System.out.println("外观模式开始操作");36 subsystemA.operationA();37 subsystemB.operationB();38 subsystemC.operationC();39 System.out.println("外观模式结束操作");40 }41}应用场景
- 系统集成
- 复杂API封装
- 第三方服务调用
4.6 享元模式(Flyweight)
模式定义
运用共享技术有效地支持大量细粒度对象的复用。
实现示例
1// 抽象享元2public abstract class Flyweight {3 public abstract void operation(String extrinsicState);4}56// 具体享元7public class ConcreteFlyweight extends Flyweight {8 private String intrinsicState;9 10 public ConcreteFlyweight(String intrinsicState) {11 this.intrinsicState = intrinsicState;12 }13 14 @Override15 public void operation(String extrinsicState) {16 System.out.println("具体享元: " + intrinsicState + ", 外部状态: " + extrinsicState);17 }18}1920// 享元工厂21public class FlyweightFactory {22 private Map<String, Flyweight> flyweights = new HashMap<>();23 24 public Flyweight getFlyweight(String key) {25 Flyweight flyweight = flyweights.get(key);26 if (flyweight == null) {27 flyweight = new ConcreteFlyweight(key);28 flyweights.put(key, flyweight);29 }30 return flyweight;31 }32 33 public int getFlyweightCount() {34 return flyweights.size();35 }36}应用场景
- 字符串池
- 数据库连接池
- 图形对象缓存
4.7 代理模式(Proxy)
模式定义
为其他对象提供一种代理以控制对这个对象的访问。
静态代理实现
1// 抽象主题2public interface Subject {3 void request();4}56// 真实主题7public class RealSubject implements Subject {8 @Override9 public void request() {10 System.out.println("真实主题的请求");11 }12}1314// 代理类15public class Proxy implements Subject {16 private RealSubject realSubject;17 18 public Proxy() {19 this.realSubject = new RealSubject();20 }21 22 @Override23 public void request() {24 preRequest();25 realSubject.request();26 postRequest();27 }28 29 private void preRequest() {30 System.out.println("代理前置处理");31 }32 33 private void postRequest() {34 System.out.println("代理后置处理");35 }36}动态代理实现
1public class DynamicProxy implements InvocationHandler {2 private Object target;3 4 public DynamicProxy(Object target) {5 this.target = target;6 }7 8 @Override9 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {10 System.out.println("动态代理前置处理");11 Object result = method.invoke(target, args);12 System.out.println("动态代理后置处理");13 return result;14 }15 16 public static Object createProxy(Object target) {17 return Proxy.newProxyInstance(18 target.getClass().getClassLoader(),19 target.getClass().getInterfaces(),20 new DynamicProxy(target)21 );22 }23}应用场景
- 远程代理
- 虚拟代理
- 保护代理
- 缓存代理
5. 行为型模式详解
5.1 责任链模式(Chain of Responsibility)
模式定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
实现示例
1// 抽象处理器2public abstract class Handler {3 protected Handler successor;4 5 public void setSuccessor(Handler successor) {6 this.successor = successor;7 }8 9 public abstract void handleRequest(int request);10}1112// 具体处理器A13public class ConcreteHandlerA extends Handler {14 @Override15 public void handleRequest(int request) {16 if (request >= 0 && request < 10) {17 System.out.println("处理器A处理请求: " + request);18 } else if (successor != null) {19 successor.handleRequest(request);20 }21 }22}2324// 具体处理器B25public class ConcreteHandlerB extends Handler {26 @Override27 public void handleRequest(int request) {28 if (request >= 10 && request < 20) {29 System.out.println("处理器B处理请求: " + request);30 } else if (successor != null) {31 successor.handleRequest(request);32 }33 }34}3536// 具体处理器C37public class ConcreteHandlerC extends Handler {38 @Override39 public void handleRequest(int request) {40 if (request >= 20 && request < 30) {41 System.out.println("处理器C处理请求: " + request);42 } else if (successor != null) {43 successor.handleRequest(request);44 } else {45 System.out.println("没有处理器能处理请求: " + request);46 }47 }48}应用场景
- 权限验证链
- 异常处理链
- 日志处理链
5.2 命令模式(Command)
模式定义
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
实现示例
1// 抽象命令2public interface Command {3 void execute();4 void undo();5}67// 具体命令8public class ConcreteCommand implements Command {9 private Receiver receiver;10 11 public ConcreteCommand(Receiver receiver) {12 this.receiver = receiver;13 }14 15 @Override16 public void execute() {17 receiver.action();18 }19 20 @Override21 public void undo() {22 receiver.undoAction();23 }24}2526// 接收者27public class Receiver {28 public void action() {29 System.out.println("接收者执行操作");30 }31 32 public void undoAction() {33 System.out.println("接收者撤销操作");34 }35}3637// 调用者38public class Invoker {39 private List<Command> commands = new ArrayList<>();40 41 public void addCommand(Command command) {42 commands.add(command);43 }44 45 public void executeCommands() {46 for (Command command : commands) {47 command.execute();48 }49 }50 51 public void undoCommands() {52 for (int i = commands.size() - 1; i >= 0; i--) {53 commands.get(i).undo();54 }55 }56}应用场景
- 菜单系统
- 宏命令
- 事务处理
5.3 观察者模式(Observer)
模式定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
实现示例
1// 抽象观察者2public interface Observer {3 void update(String message);4}56// 具体观察者A7public class ConcreteObserverA implements Observer {8 @Override9 public void update(String message) {10 System.out.println("观察者A收到消息: " + message);11 }12}1314// 具体观察者B15public class ConcreteObserverB implements Observer {16 @Override17 public void update(String message) {18 System.out.println("观察者B收到消息: " + message);19 }20}2122// 抽象主题23public abstract class Subject {24 protected List<Observer> observers = new ArrayList<>();25 26 public void attach(Observer observer) {27 observers.add(observer);28 }29 30 public void detach(Observer observer) {31 observers.remove(observer);32 }33 34 public abstract void notifyObservers();35}3637// 具体主题38public class ConcreteSubject extends Subject {39 private String state;40 41 public void setState(String state) {42 this.state = state;43 notifyObservers();44 }45 46 @Override47 public void notifyObservers() {48 for (Observer observer : observers) {49 observer.update(state);50 }51 }52}应用场景
- 事件处理
- 消息推送
- 数据绑定
5.4 策略模式(Strategy)
模式定义
定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
实现示例
1// 抽象策略2public interface Strategy {3 int doOperation(int num1, int num2);4}56// 具体策略A:加法7public class OperationAdd implements Strategy {8 @Override9 public int doOperation(int num1, int num2) {10 return num1 + num2;11 }12}1314// 具体策略B:减法15public class OperationSubtract implements Strategy {16 @Override17 public int doOperation(int num1, int num2) {18 return num1 - num2;19 }20}2122// 具体策略C:乘法23public class OperationMultiply implements Strategy {24 @Override25 public int doOperation(int num1, int num2) {26 return num1 * num2;27 }28}2930// 上下文31public class Context {32 private Strategy strategy;33 34 public Context(Strategy strategy) {35 this.strategy = strategy;36 }37 38 public void setStrategy(Strategy strategy) {39 this.strategy = strategy;40 }41 42 public int executeStrategy(int num1, int num2) {43 return strategy.doOperation(num1, num2);44 }45}应用场景
- 算法选择
- 支付方式
- 排序策略
5.5 状态模式(State)
模式定义
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
实现示例
1// 抽象状态2public abstract class State {3 protected Context context;4 5 public void setContext(Context context) {6 this.context = context;7 }8 9 public abstract void handle();10}1112// 具体状态A13public class ConcreteStateA extends State {14 @Override15 public void handle() {16 System.out.println("状态A处理");17 context.setState(new ConcreteStateB());18 }19}2021// 具体状态B22public class ConcreteStateB extends State {23 @Override24 public void handle() {25 System.out.println("状态B处理");26 context.setState(new ConcreteStateA());27 }28}2930// 上下文31public class Context {32 private State state;33 34 public Context(State state) {35 this.state = state;36 this.state.setContext(this);37 }38 39 public void setState(State state) {40 this.state = state;41 this.state.setContext(this);42 }43 44 public void request() {45 state.handle();46 }47}应用场景
- 订单状态管理
- 游戏状态
- 工作流状态
- 责任链模式:需要处理请求链时
- 命令模式:需要封装请求时
- 观察者模式:需要事件通知时
- 策略模式:需要算法选择时
- 状态模式:需要状态转换时
6. 设计原则详解
6.1 SOLID原则
单一职责原则(Single Responsibility Principle, SRP)
1// 违反SRP的类2public class UserManager {3 public void createUser(String username, String password) {4 // 用户创建逻辑5 }6 7 public void sendEmail(String to, String subject, String content) {8 // 邮件发送逻辑9 }10 11 public void saveToDatabase(User user) {12 // 数据库保存逻辑13 }14}1516// 符合SRP的类17public class UserService {18 public void createUser(String username, String password) {19 // 用户创建逻辑20 }21}2223public class EmailService {24 public void sendEmail(String to, String subject, String content) {25 // 邮件发送逻辑26 }27}2829public class UserRepository {30 public void save(User user) {31 // 数据库保存逻辑32 }33}开闭原则(Open-Closed Principle, OCP)
1// 抽象形状2public abstract class Shape {3 public abstract double calculateArea();4}56// 具体形状7public class Rectangle extends Shape {8 private double width;9 private double height;10 11 public Rectangle(double width, double height) {12 this.width = width;13 this.height = height;14 }15 16 @Override17 public double calculateArea() {18 return width * height;19 }20}2122public class Circle extends Shape {23 private double radius;24 25 public Circle(double radius) {26 this.radius = radius;27 }28 29 @Override30 public double calculateArea() {31 return Math.PI * radius * radius;32 }33}3435// 面积计算器(对扩展开放,对修改关闭)36public class AreaCalculator {37 public double calculateTotalArea(List<Shape> shapes) {38 double totalArea = 0;39 for (Shape shape : shapes) {40 totalArea += shape.calculateArea();41 }42 return totalArea;43 }44}里氏替换原则(Liskov Substitution Principle, LSP)
1// 基类2public class Bird {3 public void fly() {4 System.out.println("鸟在飞行");5 }6}78// 子类应该能够替换父类9public class Sparrow extends Bird {10 @Override11 public void fly() {12 System.out.println("麻雀在飞行");13 }14}1516// 违反LSP的子类17public class Penguin extends Bird {18 @Override19 public void fly() {20 throw new UnsupportedOperationException("企鹅不能飞行");21 }22}2324// 正确的设计25public abstract class Bird {26 public abstract void move();27}2829public class FlyingBird extends Bird {30 @Override31 public void move() {32 fly();33 }34 35 protected void fly() {36 System.out.println("鸟在飞行");37 }38}3940public class NonFlyingBird extends Bird {41 @Override42 public void move() {43 walk();44 }45 46 protected void walk() {47 System.out.println("鸟在行走");48 }49}接口隔离原则(Interface Segregation Principle, ISP)
1// 违反ISP的胖接口2public interface Worker {3 void work();4 void eat();5 void sleep();6}78// 符合ISP的细粒度接口9public interface Workable {10 void work();11}1213public interface Eatable {14 void eat();15}1617public interface Sleepable {18 void sleep();19}2021// 具体实现22public class Human implements Workable, Eatable, Sleepable {23 @Override24 public void work() {25 System.out.println("人类工作");26 }27 28 @Override29 public void eat() {30 System.out.println("人类吃饭");31 }32 33 @Override34 public void sleep() {35 System.out.println("人类睡觉");36 }37}3839public class Robot implements Workable {40 @Override41 public void work() {42 System.out.println("机器人工作");43 }44}依赖倒置原则(Dependency Inversion Principle, DIP)
1// 违反DIP的设计2public class EmailNotifier {3 public void sendEmail(String message) {4 System.out.println("发送邮件: " + message);5 }6}78public class OrderService {9 private EmailNotifier emailNotifier = new EmailNotifier();10 11 public void placeOrder(String order) {12 // 处理订单13 emailNotifier.sendEmail("订单已创建: " + order);14 }15}1617// 符合DIP的设计18public interface Notifier {19 void notify(String message);20}2122public class EmailNotifier implements Notifier {23 @Override24 public void notify(String message) {25 System.out.println("发送邮件: " + message);26 }27}2829public class SMSNotifier implements Notifier {30 @Override31 public void notify(String message) {32 System.out.println("发送短信: " + message);33 }34}3536public class OrderService {37 private Notifier notifier;38 39 public OrderService(Notifier notifier) {40 this.notifier = notifier;41 }42 43 public void placeOrder(String order) {44 // 处理订单45 notifier.notify("订单已创建: " + order);46 }47}6.2 其他重要原则
迪米特法则(Law of Demeter, LoD)
1// 违反LoD2public class Customer {3 private Wallet wallet;4 5 public Wallet getWallet() {6 return wallet;7 }8}910public class Wallet {11 private double money;12 13 public double getMoney() {14 return money;15 }16}1718// 客户端代码违反LoD19Customer customer = new Customer();20double money = customer.getWallet().getMoney(); // 违反LoD2122// 符合LoD23public class Customer {24 private Wallet wallet;25 26 public double getMoney() {27 return wallet.getMoney();28 }29}3031// 客户端代码符合LoD32Customer customer = new Customer();33double money = customer.getMoney(); // 符合LoD组合优于继承
1// 使用继承(不推荐)2public class Bird {3 public void fly() {4 System.out.println("飞行");5 }6}78public class Duck extends Bird {9 public void swim() {10 System.out.println("游泳");11 }12}1314// 使用组合(推荐)15public interface Flyable {16 void fly();17}1819public interface Swimmable {20 void swim();21}2223public class Duck {24 private Flyable flyable;25 private Swimmable swimmable;26 27 public Duck(Flyable flyable, Swimmable swimmable) {28 this.flyable = flyable;29 this.swimmable = swimmable;30 }31 32 public void fly() {33 flyable.fly();34 }35 36 public void swim() {37 swimmable.swim();38 }39}7. 实际应用场景
7.1 框架中的应用
Spring框架中的设计模式
1// 工厂模式 - BeanFactory2public interface BeanFactory {3 Object getBean(String name);4 <T> T getBean(Class<T> requiredType);5}67// 单例模式 - ApplicationContext8public class ApplicationContext {9 private static ApplicationContext instance;10 11 public static ApplicationContext getInstance() {12 if (instance == null) {13 instance = new ApplicationContext();14 }15 return instance;16 }17}1819// 代理模式 - AOP20@Aspect21@Component22public class LoggingAspect {23 @Around("@annotation(Loggable)")24 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {25 System.out.println("方法执行前");26 Object result = joinPoint.proceed();27 System.out.println("方法执行后");28 return result;29 }30}3132// 观察者模式 - 事件机制33@Component34public class OrderEventListener implements ApplicationListener<OrderEvent> {35 @Override36 public void onApplicationEvent(OrderEvent event) {37 System.out.println("处理订单事件: " + event.getOrderId());38 }39}Java集合框架中的设计模式
1// 迭代器模式2public class CustomCollection<T> implements Iterable<T> {3 private List<T> elements = new ArrayList<>();4 5 public void add(T element) {6 elements.add(element);7 }8 9 @Override10 public Iterator<T> iterator() {11 return new CustomIterator();12 }13 14 private class CustomIterator implements Iterator<T> {15 private int index = 0;16 17 @Override18 public boolean hasNext() {19 return index < elements.size();20 }21 22 @Override23 public T next() {24 if (!hasNext()) {25 throw new NoSuchElementException();26 }27 return elements.get(index++);28 }29 }30}3132// 装饰器模式33public class SynchronizedList<E> implements List<E> {34 private final List<E> list;35 36 public SynchronizedList(List<E> list) {37 this.list = list;38 }39 40 @Override41 public synchronized boolean add(E e) {42 return list.add(e);43 }44 45 @Override46 public synchronized E get(int index) {47 return list.get(index);48 }49 50 // 其他方法类似...51}7.2 业务场景应用
用户权限系统
1// 责任链模式 - 权限验证链2public abstract class PermissionHandler {3 protected PermissionHandler nextHandler;4 5 public void setNext(PermissionHandler handler) {6 this.nextHandler = handler;7 }8 9 public abstract boolean handle(PermissionRequest request);10}1112public class AuthenticationHandler extends PermissionHandler {13 @Override14 public boolean handle(PermissionRequest request) {15 if (!isAuthenticated(request)) {16 return false;17 }18 return nextHandler != null ? nextHandler.handle(request) : true;19 }20}2122public class AuthorizationHandler extends PermissionHandler {23 @Override24 public boolean handle(PermissionRequest request) {25 if (!hasPermission(request)) {26 return false;27 }28 return nextHandler != null ? nextHandler.handle(request) : true;29 }30}3132// 策略模式 - 不同验证策略33public interface ValidationStrategy {34 boolean validate(String input);35}3637public class EmailValidationStrategy implements ValidationStrategy {38 @Override39 public boolean validate(String input) {40 return input.matches("^[A-Za-z0-9+_.-]+@(.+)$");41 }42}4344public class PhoneValidationStrategy implements ValidationStrategy {45 @Override46 public boolean validate(String input) {47 return input.matches("^1[3-9]\\d{9}$");48 }49}5051// 代理模式 - 权限控制代理52public class PermissionProxy implements UserService {53 private UserService userService;54 private PermissionService permissionService;55 56 public PermissionProxy(UserService userService, PermissionService permissionService) {57 this.userService = userService;58 this.permissionService = permissionService;59 }60 61 @Override62 public void updateUser(User user) {63 if (permissionService.hasPermission("UPDATE_USER")) {64 userService.updateUser(user);65 } else {66 throw new SecurityException("没有更新用户的权限");67 }68 }69}订单系统
1// 状态模式 - 订单状态管理2public abstract class OrderState {3 protected Order order;4 5 public void setOrder(Order order) {6 this.order = order;7 }8 9 public abstract void confirm();10 public abstract void ship();11 public abstract void deliver();12 public abstract void cancel();13}1415public class PendingState extends OrderState {16 @Override17 public void confirm() {18 order.setState(new ConfirmedState());19 System.out.println("订单已确认");20 }21 22 @Override23 public void ship() {24 throw new IllegalStateException("待确认订单不能发货");25 }26 27 @Override28 public void deliver() {29 throw new IllegalStateException("待确认订单不能交付");30 }31 32 @Override33 public void cancel() {34 order.setState(new CancelledState());35 System.out.println("订单已取消");36 }37}3839// 观察者模式 - 订单事件通知40public class OrderEvent {41 private String orderId;42 private String eventType;43 private Date timestamp;44 45 // 构造函数、getter、setter46}4748public class OrderService {49 private List<OrderEventListener> listeners = new ArrayList<>();50 51 public void addListener(OrderEventListener listener) {52 listeners.add(listener);53 }54 55 public void placeOrder(Order order) {56 // 处理订单逻辑57 notifyListeners(new OrderEvent(order.getId(), "ORDER_PLACED"));58 }59 60 private void notifyListeners(OrderEvent event) {61 for (OrderEventListener listener : listeners) {62 listener.onOrderEvent(event);63 }64 }65}6667// 命令模式 - 订单操作68public interface OrderCommand {69 void execute();70 void undo();71}7273public class PlaceOrderCommand implements OrderCommand {74 private OrderService orderService;75 private Order order;76 77 public PlaceOrderCommand(OrderService orderService, Order order) {78 this.orderService = orderService;79 this.order = order;80 }81 82 @Override83 public void execute() {84 orderService.placeOrder(order);85 }86 87 @Override88 public void undo() {89 orderService.cancelOrder(order.getId());90 }91}8. 性能考虑
8.1 模式选择对性能的影响
创建型模式性能分析
1// 单例模式 - 内存占用最小2public class Singleton {3 private static Singleton instance;4 5 public static Singleton getInstance() {6 if (instance == null) {7 instance = new Singleton();8 }9 return instance;10 }11}1213// 工厂模式 - 对象创建开销14public class Factory {15 public Product createProduct(String type) {16 switch (type) {17 case "A": return new ProductA();18 case "B": return new ProductB();19 default: throw new IllegalArgumentException();20 }21 }22}2324// 原型模式 - 克隆开销25public class Prototype implements Cloneable {26 private List<String> data = new ArrayList<>();27 28 @Override29 public Prototype clone() {30 try {31 Prototype clone = (Prototype) super.clone();32 clone.data = new ArrayList<>(this.data); // 深拷贝开销33 return clone;34 } catch (CloneNotSupportedException e) {35 throw new RuntimeException(e);36 }37 }38}结构型模式性能分析
1// 代理模式 - 方法调用开销2public class Proxy implements Subject {3 private RealSubject realSubject;4 5 @Override6 public void request() {7 // 前置处理8 long start = System.currentTimeMillis();9 10 realSubject.request();11 12 // 后置处理13 long end = System.currentTimeMillis();14 System.out.println("方法执行时间: " + (end - start) + "ms");15 }16}1718// 装饰器模式 - 对象包装开销19public class Decorator implements Component {20 private Component component;21 22 @Override23 public void operation() {24 // 装饰逻辑25 component.operation();26 // 装饰逻辑27 }28}2930// 享元模式 - 内存优化31public class FlyweightFactory {32 private Map<String, Flyweight> flyweights = new HashMap<>();33 34 public Flyweight getFlyweight(String key) {35 return flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight(k));36 }37}8.2 优化策略
对象池模式
1public class ObjectPool<T> {2 private final Supplier<T> factory;3 private final Queue<T> pool;4 private final int maxSize;5 6 public ObjectPool(Supplier<T> factory, int maxSize) {7 this.factory = factory;8 this.maxSize = maxSize;9 this.pool = new ConcurrentLinkedQueue<>();10 }11 12 public T borrow() {13 T object = pool.poll();14 return object != null ? object : factory.get();15 }16 17 public void release(T object) {18 if (pool.size() < maxSize) {19 pool.offer(object);20 }21 }22}2324// 使用示例25ObjectPool<Connection> connectionPool = new ObjectPool<>(26 () -> createConnection(), 27 1028);2930Connection conn = connectionPool.borrow();31try {32 // 使用连接33} finally {34 connectionPool.release(conn);35}延迟加载
1public class LazySingleton {2 private static volatile LazySingleton instance;3 4 public static LazySingleton getInstance() {5 if (instance == null) {6 synchronized (LazySingleton.class) {7 if (instance == null) {8 instance = new LazySingleton();9 }10 }11 }12 return instance;13 }14}1516public class LazyInitialization {17 private volatile ExpensiveObject expensiveObject;18 19 public ExpensiveObject getExpensiveObject() {20 if (expensiveObject == null) {21 synchronized (this) {22 if (expensiveObject == null) {23 expensiveObject = new ExpensiveObject();24 }25 }26 }27 return expensiveObject;28 }29}9. 面试题精选
9.1 基础概念题
Q1: 设计模式的分类和特点是什么?
答: 设计模式按目的分为三大类:
创建型模式:
- 解决对象创建问题
- 包括:单例、工厂方法、抽象工厂、建造者、原型
- 特点:封装对象创建过程,提高系统灵活性
结构型模式:
- 解决对象组合问题
- 包括:适配器、桥接、组合、装饰器、外观、享元、代理
- 特点:关注对象间的组合关系
行为型模式:
- 解决对象交互问题
- 包括:责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者
- 特点:关注对象间的通信机制
Q2: SOLID原则的含义是什么?
答: SOLID是面向对象设计的五个基本原则:
- S - 单一职责原则:一个类应该只有一个变化的原因
- O - 开闭原则:对扩展开放,对修改关闭
- L - 里氏替换原则:子类应该能够替换父类
- I - 接口隔离原则:客户端不应该依赖它不需要的接口
- D - 依赖倒置原则:依赖抽象而不是具体实现
Q3: 设计模式和设计原则的区别是什么?
答:
- 设计原则:是指导设计的基本准则,如SOLID原则
- 设计模式:是解决特定问题的具体方案,如23种经典模式
- 关系:设计模式是设计原则的具体应用和体现
9.2 具体模式题
Q4: 单例模式的线程安全实现有哪些?
答:
- 饿汉式:类加载时就初始化,线程安全
1public class Singleton {2 private static final Singleton instance = new Singleton();3 private Singleton() {}4 public static Singleton getInstance() { return instance; }5}- 双重检查锁定:延迟加载,线程安全
1public class Singleton {2 private static volatile Singleton instance;3 private Singleton() {}4 public static Singleton getInstance() {5 if (instance == null) {6 synchronized (Singleton.class) {7 if (instance == null) {8 instance = new Singleton();9 }10 }11 }12 return instance;13 }14}- 枚举实现:最简单,自动线程安全
1public enum Singleton {2 INSTANCE;3 public void doSomething() {}4}Q5: 工厂模式和抽象工厂的区别是什么?
答: 工厂方法模式:
- 定义一个创建对象的接口,让子类决定实例化哪个类
- 适用于单一产品族
- 扩展新产品时需要修改工厂类
抽象工厂模式:
- 提供一个创建一系列相关对象的接口
- 适用于多个产品族
- 扩展新产品族时需要修改抽象工厂接口
Q6: 装饰器模式和代理模式的区别是什么?
答: 装饰器模式:
- 目的:动态添加功能
- 关系:装饰器与被装饰对象实现相同接口
- 特点:可以多层装饰,功能叠加
代理模式:
- 目的:控制对象访问
- 关系:代理与被代理对象实现相同接口
- 特点:通常只有一层代理,控制访问
9.3 实际应用题
Q7: 如何在项目中应用设计模式?
答:
- 识别问题:分析代码中的重复问题和不合理设计
- 选择模式:根据问题类型选择合适的模式
- 重构代码:逐步重构,保持向后兼容
- 测试验证:确保重构后功能正确
- 文档记录:记录模式应用的原因和效果
Q8: 如何避免过度设计?
答:
- YAGNI原则:You Aren't Gonna Need It,不要过早优化
- 简单优先:优先使用简单直接的解决方案
- 实际需求:只在确实需要时才使用设计模式
- 团队共识:确保团队理解模式的使用
- 持续重构:随着需求变化调整设计
Q9: 如何评估设计模式的效果?
答:
- 代码质量:可读性、可维护性、可扩展性
- 性能影响:内存使用、执行效率
- 复杂度:代码复杂度是否合理
- 团队接受度:团队成员是否理解和使用
- 业务价值:是否解决了实际问题
9.4 性能优化题
Q10: 设计模式对性能的影响有哪些?
答: 正面影响:
- 提高代码复用性,减少重复代码
- 优化对象创建和销毁
- 改善内存使用模式
负面影响:
- 增加代码复杂度
- 引入额外的对象和方法调用
- 可能增加内存占用
优化策略:
- 合理选择模式,避免过度使用
- 使用对象池减少创建开销
- 采用延迟加载优化初始化
- 考虑缓存机制提高性能
- 理解原理:深入理解每个模式的核心思想
- 实践应用:在实际项目中应用设计模式
- 权衡取舍:根据具体场景选择合适的模式
- 持续学习:关注新的设计模式和最佳实践
- 团队协作:与团队分享和交流设计经验
通过本章的学习,你应该已经掌握了设计模式的核心概念、分类体系、实际应用和最佳实践。设计模式是提高代码质量的重要工具,但需要根据具体场景合理使用,避免过度设计。在实际项目中,要结合业务需求和团队能力,选择合适的设计模式,并持续优化和改进。
评论区 / Comments