设计模式
目录
面向对象设计原则
单一职责原则 (Single Responsibility Principle)
定义:一个类应该只有一个引起它变化的原因。
核心思想:一个类只负责一项职责。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class User { public void saveUser() { } public void sendEmail() { } public void calculateSalary() { } }
class UserRepository { public void saveUser() { } } class EmailService { public void sendEmail() { } } class SalaryCalculator { public void calculateSalary() { } }
|
开闭原则 (Open/Closed Principle)
定义:软件实体应该对扩展开放,对修改关闭。
核心思想:通过添加新代码来扩展功能,而不是修改已有代码。
示例:
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
| class PaymentProcessor { public void processPayment(String type) { if (type.equals("ALIPAY")) { } else if (type.equals("WECHAT")) { } } }
interface Payment { void pay(); } class AliPay implements Payment { public void pay() { } } class WeChatPay implements Payment { public void pay() { } } class PaymentProcessor { public void processPayment(Payment payment) { payment.pay(); } }
|
里氏替换原则 (Liskov Substitution Principle)
定义:所有引用基类的地方必须能透明地使用其子类的对象。
核心要点:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
- 子类可以增加自己特有的方法
- 子类重写/重载父类方法时,前置条件更宽松,后置条件更严格
示例:
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
| class Rectangle { protected int width, height; public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } public int getArea() { return width * height; } } class Square extends Rectangle { @Override public void setWidth(int w) { super.setWidth(w); super.setHeight(w); } @Override public void setHeight(int h) { super.setWidth(h); super.setHeight(h); } }
abstract class Shape { public abstract int getArea(); } class Rectangle extends Shape { private int width, height; public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } public int getArea() { return width * height; } } class Square extends Shape { private int side; public void setSide(int s) { side = s; } public int getArea() { return side * side; } }
|
依赖倒转原则 (Dependency Inversion Principle)
定义:高层模块不应依赖于底层模块,它们都应该依赖抽象。抽象不应依赖于细节,细节应该依赖于抽象。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class OrderService { private MySQLOrderDao dao = new MySQLOrderDao(); public void saveOrder() { dao.save(); } } class MySQLOrderDao { public void save() { } }
interface OrderDao { void save(); } class MySQLOrderDao implements OrderDao { public void save() { } } class OrderService { private OrderDao dao; public OrderService(OrderDao dao) { this.dao = dao; } public void saveOrder() { dao.save(); } }
|
接口隔离原则 (Interface Segregation Principle)
定义:客户端不应该依赖它不需要的接口。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| interface Animal { void fly(); void swim(); void run(); } class Dog implements Animal { public void fly() { } public void swim() { } public void run() { } }
interface Flyable { void fly(); } interface Swimmable { void swim(); } interface Runnable { void run(); } class Dog implements Swimmable, Runnable { public void swim() { } public void run() { } }
|
合成复用原则 (Composite Reuse Principle)
定义:尽量使用对象组合,而不是继承来达到复用的目的。
示例:
1 2 3 4 5 6 7 8 9 10 11 12
| class Car extends Engine { }
class Engine { public void start() { } } class Car { private Engine engine; public Car(Engine engine) { this.engine = engine; } public void start() { engine.start(); } }
|
迪米特法则 (Law of Demeter)
定义:一个对象应该对其他对象保持最少的了解。只与直接的朋友通信。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Customer { public Wallet getWallet() { return wallet; } } class Wallet { public void reduceMoney(int amount) { } } class Store { public void charge(Customer customer, int amount) { customer.getWallet().reduceMoney(amount); } }
class Customer { public void pay(int amount) { wallet.reduceMoney(amount); } } class Store { public void charge(Customer customer, int amount) { customer.pay(amount); } }
|
创建型模式
单例模式 (Singleton)
定义:确保一个类只有一个实例,并提供一个全局的访问点。
适用场景:数据库连接池、配置管理、日志对象等。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| ┌─────────────────────────────────────────────────┐ │ 请求获取实例 │ └──────────────────┬──────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────┐ │ 实例是否已存在? │ └──────────────────┬──────────────────────────────┘ ┌─────┴─────┐ │ │ 是 否 │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ 返回实例 │ │ 创建实例 │ └─────────────┘ └──────┬──────┘ │ │ └──────┬──────┘ │ ▼ ┌─────────────┐ │ 返回实例 │ └─────────────┘
|
1. 饿汉式 (Eager Initialization)
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton { private static final Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() { return INSTANCE; } }
|
优缺点:
- 优点:线程安全,实现简单
- 缺点:类加载时就初始化,浪费内存
2. 懒汉式 (Lazy Initialization)
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private static Singleton instance;
private Singleton() { }
public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
|
优缺点:
3. 双重检查锁 (Double-Checked Locking)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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; } }
|
关键点:
volatile 防止指令重排序- 双重检查保证线程安全且高效
4. 静态内部类 (Static Inner Class)
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton { private Singleton() { }
private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
|
优缺点:
- 优点:线程安全,延迟加载,效率高
- 缺点:无法传递参数困难
5. 枚举 (Enum)
1 2 3 4 5 6 7 8 9 10
| public enum Singleton { INSTANCE;
public void doSomething() { } }
Singleton.INSTANCE.doSomething();
|
优缺点:
- 优点:最简单,线程安全,防止反射和序列化攻击
- 缺点:无法继承
面试常见问题
**为什么双重检查锁需要 volatile?
- 防止
instance = new Singleton() 的指令重排序
**如何防止反射破坏单例?
如何防止序列化破坏单例?
- 实现
readResolve() 方法返回单例 - 使用枚举
工厂模式
简单工厂模式
定义:由一个工厂类根据传入的参数,动态决定创建哪一个产品类的实例。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ┌──────────────┐ │ Client │ └──────┬─────┘ │ ▼ ┌──────────────┐ │ Factory │ └──────┬─────┘ ┌────────────┼────────────┐ │ │ │ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ │ProductA│ │ProductB│ │ProductC│ └────────┘ └────────┘ └────────┘
|
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| interface Product { void use(); } class ProductA implements Product { public void use() { System.out.println("使用产品A"); } } class ProductB implements Product { public void use() { System.out.println("使用产品B"); } } class SimpleFactory { public static Product createProduct(String type) { switch (type) { case "A": return new ProductA(); case "B": return new ProductB(); default: return null; } } }
Product product = SimpleFactory.createProduct("A"); product.use();
|
工厂方法模式
定义:定义一个创建对象的接口,但让子类决定实例化哪一个类。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──────────────┐ │ Client │ └──────┬─────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │FactoryA │ │FactoryB │ │FactoryC │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ProductA │ │ProductB │ │ProductC │ └──────────┘ └──────────┘ └──────────┘
|
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| interface Product { void use(); } interface Factory { Product createProduct(); } class ProductA implements Product { public void use() { System.out.println("使用产品A"); } } class FactoryA implements Factory { public Product createProduct() { return new ProductA(); } } class ProductB implements Product { public void use() { System.out.println("使用产品B"); } } class FactoryB implements Factory { public Product createProduct() { return new ProductB(); } }
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 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| interface Button { void click(); } interface TextField { void input(); }
class WindowsButton implements Button { public void click() { System.out.println("Windows按钮"); } } class WindowsTextField implements TextField { public void input() { System.out.println("Windows输入框"); } } class MacButton implements Button { public void click() { System.out.println("Mac按钮"); } } class MacTextField implements TextField { public void input() { System.out.println("Mac输入框"); } }
interface GUIFactory { Button createButton(); TextField createTextField(); } class WindowsFactory implements GUIFactory { public Button createButton() { return new WindowsButton(); } public TextField createTextField() { return new WindowsTextField(); } } class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); } public TextField createTextField() { return new MacTextField(); } }
GUIFactory factory = new WindowsFactory(); Button button = factory.createButton(); TextField textField = factory.createTextField(); button.click(); textField.input();
|
工厂模式面试常见问题
**简单工厂 vs 工厂方法 vs 抽象工厂的区别?
- 简单工厂:一个工厂创建所有产品
- 工厂方法:每个产品对应一个工厂
- 抽象工厂:创建产品族
Spring框架中如何使用工厂模式?
建造者模式 (Builder)
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ┌──────────────┐ │ Director │ └──────┬─────┘ │ ┌──────▼──────┐ │ Builder │ └──────┬─────┘ ┌─────────────────┼─────────────────┐ │ │ │ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ │Builder1 │ │Builder2 │ │Builder3 │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └─────────────────┼─────────────────┘ │ ┌──────▼──────┐ │ Product │ └──────────────┘
|
代码示例:
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
| class Computer { private String cpu; private String ram; private String storage; private String gpu;
private Computer(Builder builder) { this.cpu = builder.cpu; this.ram = builder.ram; this.storage = builder.storage; this.gpu = builder.gpu; }
public static class Builder { private String cpu; private String ram; private String storage; private String gpu;
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 Computer build() { return new Computer(this); } }
@Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", ram='" + ram + '\'' + ", storage='" + storage + '\'' + ", gpu='" + gpu + '\'' + '}'; } }
Computer computer = new Computer.Builder() .cpu("i9") .ram("32GB") .storage("1TB SSD") .gpu("RTX4090") .build(); System.out.println(computer);
|
原型模式 (Prototype)
定义:通过复制现有实例来创建新实例,而不是通过new关键字。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Prototype implements Cloneable { private String name; private List<String> list;
public Prototype(String name, List<String> list) { this.name = name; this.list = list; }
@Override public Prototype clone() throws CloneNotSupportedException { return (Prototype) super.clone(); }
public Prototype deepClone() { Prototype copy = new Prototype(this.name, new ArrayList<>(this.list)); return copy; } }
|
结构型模式
适配器模式 (Adapter)
定义:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
流程图:
1 2 3 4 5 6 7 8 9 10 11
| ┌──────────────┐ │ Target │ └──────┬─────┘ │ ┌──────▼──────┐ │ Adapter │ └──────┬─────┘ │ ┌──────▼──────┐ │ Adaptee │ └──────────────┘
|
代码示例:
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
| 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(); } }
Target target = new Adapter(new Adaptee()); target.request();
|
装饰器模式 (Decorator)
定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更为灵活。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──────────────┐ │ Component │ └──────┬─────┘ ┌───────────┴───────────┐ │ │ ┌────▼─────┐ ┌──────▼──────┐ │Concrete │ │ Decorator │ │Component│ └──────┬─────┘ └──────────┘ │ ┌─┴─┐ │ │ ┌────▼─────┐ │Concrete │ │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
| interface Coffee { String getDescription(); double getCost(); }
class SimpleCoffee implements Coffee { public String getDescription() { return "简单咖啡"; } public double getCost() { return 10.0; } }
abstract class CoffeeDecorator implements Coffee { protected Coffee coffee; public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; } }
class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } public String getDescription() { return coffee.getDescription() + ", 加牛奶"; } public double getCost() { return coffee.getCost() + 2.0; } } class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); } public String getDescription() { return coffee.getDescription() + ", 加糖"; } 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() + " = " + coffee.getCost());
|
代理模式 (Proxy)
定义:为其他对象提供一种代理以控制对这个对象的访问。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ┌──────────────┐ │ Subject │ └──────┬─────┘ ┌───────────┴───────────┐ │ │ ┌────▼─────┐ ┌──────▼──────┐ │ Real │ │ Proxy │ │ Subject │ └──────┬─────┘ └──────────┘ │ │ ┌──────────┴──────────┐ │ │ ┌────▼─────┐ ┌──────▼──────┐ │ 控制访问 │ │ 调用真实 │ └──────────┘ │ 对象 │ └──────────────┘
|
代码示例:
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
| 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("加载 " + fileName); }
public void display() { System.out.println("显示 " + 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(); } }
Image image = new ProxyImage("test.jpg"); image.display(); image.display();
|
外观模式 (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
| class CPU { public void start() { System.out.println("CPU启动"); } } class Memory { public void load() { System.out.println("内存加载"); } } class Disk { public void read() { System.out.println("磁盘读取"); } }
class ComputerFacade { private CPU cpu; private Memory memory; private Disk disk;
public ComputerFacade() { this.cpu = new CPU(); this.memory = new Memory(); this.disk = new Disk(); }
public void start() { cpu.start(); memory.load(); disk.read(); System.out.println("电脑启动完成"); } }
ComputerFacade computer = new ComputerFacade(); computer.start();
|
桥接模式 (Bridge)
定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
代码示例:
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
| interface Color { String getColor(); } class Red implements Color { public String getColor() { return "红色"; } } class Blue implements Color { public String getColor() { return "蓝色"; } }
abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); } class Circle extends Shape { public Circle(Color color) { super(color); } public void draw() { System.out.println("画一个" + color.getColor() + "圆"); } } class Square extends Shape { public Square(Color color) { super(color); } public void draw() { System.out.println("画一个" + color.getColor() + "正方形"); } }
Color red = new Red(); Shape redCircle = new Circle(red); redCircle.draw();
|
组合模式 (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
| import java.util.ArrayList; import java.util.List;
abstract class Component { protected String name; public Component(String name) { this.name = name; } public abstract void add(Component component); public abstract void remove(Component component); public abstract void display(int depth); }
class Leaf extends Component { public Leaf(String name) { super(name); } public void add(Component component) { System.out.println("叶子节点不能添加"); } public void remove(Component component) { System.out.println("叶子节点不能删除"); } public void display(int depth) { for (int i = 0; i < depth; i++) { System.out.print("-"); } System.out.println(name); } }
class Composite extends Component { private List<Component> children = new ArrayList<>(); public Composite(String name) { super(name); } public void add(Component component) { children.add(component); } public void remove(Component component) { children.remove(component); } public void display(int depth) { for (int i = 0; i < depth; i++) { System.out.print("-"); } System.out.println(name); for (Component component : children) { component.display(depth + 2); } } }
Composite root = new Composite("根目录"); root.add(new Leaf("文件1.txt")); Composite dir1 = new Composite("文件夹1"); dir1.add(new Leaf("文件2.txt")); root.add(dir1); root.display(0);
|
行为型模式
策略模式 (Strategy)
定义:定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。本模式使得算法可独立于使用它的客户而变化。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12
| ┌──────────────┐ │ Context │ └──────┬─────┘ │ ┌──────▼──────┐ │ Strategy │ └──────┬─────┘ ┌─────────────────┼─────────────────┐ │ │ │ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ │Strategy1 │ │Strategy2 │ │Strategy3 │ └──────────┘ └──────────┘ └──────────┘
|
代码示例:
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
| interface PaymentStrategy { void pay(double amount); }
class AliPayStrategy implements PaymentStrategy { public void pay(double amount) { System.out.println("支付宝支付: " + amount); } } class WeChatPayStrategy implements PaymentStrategy { public void pay(double amount) { System.out.println("微信支付: " + amount); } } class CreditCardStrategy implements PaymentStrategy { public void pay(double amount) { System.out.println("信用卡支付: " + amount); } }
class PaymentContext { private PaymentStrategy strategy; public PaymentContext(PaymentStrategy strategy) { this.strategy = strategy; } public void executePayment(double amount) { strategy.pay(amount); } }
PaymentContext context = new PaymentContext(new AliPayStrategy()); context.executePayment(100.0);
|
观察者模式 (Observer)
定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──────────────┐ │ Subject │ └──────┬─────┘ ┌───────────┴───────────┐ │ │ ┌────▼─────┐ ┌──────▼──────┐ │ attach() │ │ detach() │ │ notify() │ └──────────────┘ └────┬─────┘ │ ┌────┴─────┐ │ │ ┌────▼─────┐ ┌────▼─────┐ │ Observer1 │ │ Observer2 │ └──────────┘ └──────────┘
|
代码示例:
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
| import java.util.ArrayList; import java.util.List;
interface Subject { void attach(Observer observer); void detach(Observer observer); void notifyObservers(); }
interface Observer { void update(String message); }
class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); private String state;
public void setState(String state) { this.state = state; notifyObservers(); }
public void attach(Observer observer) { observers.add(observer); } public void detach(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); } }
Subject subject = new ConcreteSubject(); subject.attach(new ConcreteObserver("观察者1")); subject.attach(new ConcreteObserver("观察者2")); ((ConcreteSubject) subject).setState("状态更新");
|
模板方法模式 (Template Method)
定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
流程图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ┌─────────────────────────┐ │ AbstractClass │ │ ───────────── │ │ + templateMethod() │ │ - primitive1() │ │ - primitive2() │ └───────────┬─────────────┘ │ ┌───────────┴─────────────┐ │ │ ┌──────────▼──────────┐ ┌──────────▼──────────┐ │ ConcreteClass1 │ │ ConcreteClass2 │ │ ─────────────── │ │ ─────────────── │ │ - primitive1() │ │ - primitive1() │ │ - primitive2() │ │ - primitive2() │ └───────────────────────┘ └───────────────────────┘
|
代码示例:
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
| abstract class BankTemplate { public final void processBusiness() { takeNumber(); transact(); evaluate(); }
protected void takeNumber() { System.out.println("取号排队"); }
protected abstract void transact();
protected void evaluate() { System.out.println("服务评价"); } }
class DepositBusiness extends BankTemplate { protected void transact() { System.out.println("办理存款业务"); } } class WithdrawBusiness extends BankTemplate { protected void transact() { System.out.println("办理取款业务"); } }
BankTemplate business = new DepositBusiness(); business.processBusiness();
|
责任链模式 (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
| abstract class Handler { protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; }
public abstract void handleRequest(int request); }
class ConcreteHandlerA extends Handler { public void handleRequest(int request) { if (request < 10) { System.out.println("HandlerA处理请求: " + request); } else if (nextHandler != null) { nextHandler.handleRequest(request); } } } class ConcreteHandlerB extends Handler { public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println("HandlerB处理请求: " + request); } else if (nextHandler != null) { nextHandler.handleRequest(request); } } }
Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); handlerA.setNextHandler(handlerB); handlerA.handleRequest(5); handlerA.handleRequest(15);
|
命令模式 (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
| interface Command { void execute(); void undo(); }
class Light { public void on() { System.out.println("灯打开了"); } public void off() { System.out.println("灯关上了"); } }
class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } public void undo() { light.off(); } } class LightOffCommand implements Command { private Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.off(); } public void undo() { light.on(); } }
class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } public void pressUndo() { command.undo(); } }
Light light = new Light(); Command onCommand = new LightOnCommand(light); RemoteControl remote = new RemoteControl(); remote.setCommand(onCommand); remote.pressButton(); remote.pressUndo();
|
状态模式 (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
| interface State { void handle(Context context); }
class Context { private State state; public void setState(State state) { this.state = state; } public void request() { state.handle(this); } }
class ConcreteStateA implements State { public void handle(Context context) { System.out.println("当前状态是A,切换到B"); context.setState(new ConcreteStateB()); } } class ConcreteStateB implements State { public void handle(Context context) { System.out.println("当前状态是B,切换到A"); context.setState(new ConcreteStateA()); } }
Context context = new Context(); context.setState(new ConcreteStateA()); context.request(); context.request();
|
迭代器模式 (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 49
| import java.util.ArrayList; import java.util.List;
interface Iterator<T> { boolean hasNext(); T next(); }
interface Aggregate<T> { Iterator<T> createIterator(); }
class ConcreteAggregate<T> implements Aggregate<T> { private List<T> items = new ArrayList<>(); public void add(T item) { items.add(item); } public T get(int index) { return items.get(index); } public int size() { return items.size(); } public Iterator<T> createIterator() { return new ConcreteIterator<>(this); } }
class ConcreteIterator<T> implements Iterator<T> { private ConcreteAggregate<T> aggregate; private int index = 0; public ConcreteIterator(ConcreteAggregate<T> aggregate) { this.aggregate = aggregate; } public boolean hasNext() { return index < aggregate.size(); } public T next() { return aggregate.get(index++); } }
ConcreteAggregate<String> aggregate = new ConcreteAggregate<>(); aggregate.add("A"); aggregate.add("B"); aggregate.add("C"); Iterator<String> iterator = aggregate.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
|
设计模式面试总结
常见面试问题
**设计模式的六大原则是什么?
- 单一职责、开闭原则、里氏替换、依赖倒转、接口隔离、迪米特法则
**单例模式的几种实现方式及其优缺点?
**工厂模式三种形态的区别?
**代理模式和装饰器模式的区别?
**Spring中使用了哪些设计模式?
**JDK中使用了哪些设计模式?
- 适配器模式(InputStreamReader)
- 装饰器模式(IO流)
- 单例模式(Runtime)
- 迭代器模式(Iterator)
设计模式选择建议
| 问题场景 | 推荐模式 |
|---|
| 需要唯一实例 | 单例模式 |
| 创建复杂对象 | 建造者模式 |
| 需灵活创建对象 | 工厂模式 |
| 需动态增加功能 | 装饰器模式 |
| 需控制对象访问 | 代理模式 |
| 需简化子系统接口 | 外观模式 |
| 算法需灵活切换 | 策略模式 |
| 一对多通知 | 观察者模式 |
| 算法骨架固定,步骤变化 | 模板方法 |