以下是Java 23种设计模式的详细解析,包含意图、特点、实现要点及代码演示,按创建型、结构型、行为型分类整理:

一、创建型模式(5种)

专注于对象创建机制,隐藏创建逻辑,提高灵活性。

1. 单例模式(Singleton)

意图:确保一个类仅有一个实例,并提供全局访问点。

特点:

唯一实例,全局可访问;

避免频繁创建销毁,节省资源;

需处理线程安全问题。

实现要点:

私有构造器阻止外部实例化;

静态方法/变量持有唯一实例。

// 饿汉式(线程安全,类加载时初始化)

public class Singleton {

private static final Singleton INSTANCE = new Singleton();

private Singleton() {} // 私有构造器

public static Singleton getInstance() { return INSTANCE; }

}

// 懒汉式(双重校验锁,延迟初始化)

public class LazySingleton {

private static volatile LazySingleton instance;

private LazySingleton() {}

public static LazySingleton getInstance() {

if (instance == null) {

synchronized (LazySingleton.class) {

if (instance == null) {

instance = new LazySingleton();

}

}

}

return instance;

}

}

2. 工厂模式(Factory)

意图:通过工厂类封装对象创建逻辑,客户端无需关注具体实现。

特点:

解耦对象创建与使用;

新增产品只需扩展工厂,符合开闭原则;

适用于产品类型较少的场景。

实现要点:

定义产品接口;

工厂类根据参数返回具体产品实例。

// 产品接口

interface Shape { void draw(); }

// 具体产品

class Circle implements Shape {

@Override public void draw() { System.out.println("画圆形"); }

}

// 工厂类

class ShapeFactory {

public Shape getShape(String type) {

if (type.equalsIgnoreCase("CIRCLE")) return new Circle();

return null;

}

}

// 使用

public class FactoryDemo {

public static void main(String[] args) {

ShapeFactory factory = new ShapeFactory();

factory.getShape("CIRCLE").draw(); // 输出:画圆形

}

}

3. 抽象工厂模式(Abstract Factory)

意图:创建一系列相关或依赖的产品族,无需指定具体类。

特点:

针对“产品族”(如“现代家具”包含椅子、桌子);

切换产品族只需更换工厂,客户端无需修改;

新增产品需修改工厂接口,灵活性较低。

实现要点:

抽象工厂定义产品族的创建方法;

具体工厂实现特定产品族的创建。

// 抽象产品

interface Chair { void sit(); }

interface Table { void put(); }

// 具体产品(现代风格)

class ModernChair implements Chair {

@Override public void sit() { System.out.println("坐现代椅子"); }

}

// 抽象工厂

interface FurnitureFactory {

Chair createChair();

Table createTable();

}

// 具体工厂

class ModernFactory implements FurnitureFactory {

@Override public Chair createChair() { return new ModernChair(); }

@Override public Table createTable() { return new ModernTable(); }

}

// 使用

public class AbstractFactoryDemo {

public static void main(String[] args) {

FurnitureFactory factory = new ModernFactory();

factory.createChair().sit(); // 输出:坐现代椅子

}

}

4. 建造者模式(Builder)

意图:分步构建复杂对象,分离构建过程与最终表示。

特点:

步骤清晰,支持定制对象的不同部件;

同一构建过程可生成不同产品;

由指挥者控制构建顺序。

实现要点:

建造者接口定义部件构建方法;

指挥者调用建造者方法完成组装。

// 产品

class Computer {

private String cpu;

private String ram;

// getter/setter省略

}

// 建造者接口

interface ComputerBuilder {

void buildCpu();

void buildRam();

Computer getResult();

}

// 具体建造者(高配电脑)

class HighEndBuilder implements ComputerBuilder {

private Computer computer = new Computer();

@Override public void buildCpu() { computer.setCpu("i9"); }

@Override public void buildRam() { computer.setRam("32GB"); }

@Override public Computer getResult() { return computer; }

}

// 指挥者

class Director {

public Computer construct(ComputerBuilder builder) {

builder.buildCpu();

builder.buildRam();

return builder.getResult();

}

}

// 使用

public class BuilderDemo {

public static void main(String[] args) {

Computer computer = new Director().construct(new HighEndBuilder());

System.out.println(computer.getCpu()); // 输出:i9

}

}

5. 原型模式(Prototype)

意图:通过复制现有对象创建新对象,避免重复初始化。

特点:

简化创建流程,适合初始化耗时的对象;

分为浅拷贝(引用类型共享)和深拷贝(完全复制);

无需知道类名即可创建对象。

实现要点:

实现Cloneable接口;

重写clone()方法实现复制逻辑。

class Sheep implements Cloneable {

private String name;

public Sheep(String name) { this.name = name; }

@Override protected Sheep clone() throws CloneNotSupportedException {

return (Sheep) super.clone(); // 浅拷贝

}

}

// 使用

public class PrototypeDemo {

public static void main(String[] args) throws CloneNotSupportedException {

Sheep original = new Sheep("多利");

Sheep clone = original.clone();

System.out.println(clone.name); // 输出:多利

}

}

二、结构型模式(7种)

处理类或对象的组合,优化结构以实现功能复用。

6. 适配器模式(Adapter)

意图:将一个类的接口转换为客户端期望的另一个接口。

特点:

解决接口不兼容问题(如旧系统对接新系统);

分为类适配器(继承)和对象适配器(组合,更灵活);

不修改原有代码,符合开闭原则。

实现要点:

适配器实现目标接口;

内部持有适配者实例,转发请求。

// 目标接口

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; }

@Override public void request() { adaptee.specificRequest(); }

}

// 使用

public class AdapterDemo {

public static void main(String[] args) {

Target target = new Adapter(new Adaptee());

target.request(); // 输出:适配者方法

}

}

7. 装饰器模式(Decorator)

意图:动态给对象添加额外功能,不改变其结构。

特点:

比继承更灵活,可多层嵌套装饰;

装饰器与被装饰者实现同一接口,客户端透明;

适用于功能扩展频繁的场景(如IO流)。

实现要点:

装饰器抽象类实现组件接口,并持有组件实例;

具体装饰器扩展额外功能。

// 抽象组件

interface Coffee {

String getDesc();

double cost();

}

// 具体组件(基础咖啡)

class SimpleCoffee implements Coffee {

@Override public String getDesc() { return "纯咖啡"; }

@Override public double cost() { return 5.0; }

}

// 装饰器

class MilkDecorator extends CoffeeDecorator {

public MilkDecorator(Coffee coffee) { super(coffee); }

@Override public String getDesc() { return super.getDesc() + " + 牛奶"; }

@Override public double cost() { return super.cost() + 2.0; }

}

// 使用

public class DecoratorDemo {

public static void main(String[] args) {

Coffee coffee = new MilkDecorator(new SimpleCoffee());

System.out.println(coffee.getDesc() + ":" + coffee.cost()); // 纯咖啡 + 牛奶:7.0

}

}

8. 代理模式(Proxy)

意图:为对象提供代理,控制对原对象的访问。

特点:

代理与目标对象实现同一接口,客户端无感知;

可实现权限控制、延迟加载、日志记录等;

分为静态代理和动态代理(如JDK Proxy)。

实现要点:

代理类持有目标对象引用;

代理方法中添加额外逻辑后调用目标方法。

// 抽象主题

interface Image { void display(); }

// 真实主题(耗时操作)

class RealImage implements Image {

private String filename;

public RealImage(String filename) { this.filename = filename; load(); }

private void load() { System.out.println("加载图片:" + filename); }

@Override public void display() { System.out.println("显示图片"); }

}

// 代理类(延迟加载)

class ProxyImage implements Image {

private RealImage realImage;

private String filename;

public ProxyImage(String filename) { this.filename = filename; }

@Override public void display() {

if (realImage == null) realImage = new RealImage(filename);

realImage.display();

}

}

// 使用

public class ProxyDemo {

public static void main(String[] args) {

Image image = new ProxyImage("photo.jpg");

image.display(); // 首次:加载并显示;再次:直接显示

}

}

9. 外观模式(Facade)

意图:为子系统提供统一接口,简化客户端访问。

特点:

封装子系统复杂性,提供“一站式”接口;

隔离客户端与子系统,降低耦合;

不改变子系统内部逻辑。

实现要点:

外观类持有子系统实例;

提供高层方法封装子系统交互。

// 子系统

class DVDPlayer { public void on() { System.out.println("DVD打开"); } }

class Projector { public void on() { System.out.println("投影仪打开"); } }

// 外观类

class HomeTheaterFacade {

private DVDPlayer dvd;

private Projector projector;

public HomeTheaterFacade(DVDPlayer dvd, Projector projector) {

this.dvd = dvd;

this.projector = projector;

}

public void watchMovie() {

projector.on();

dvd.on();

}

}

// 使用

public class FacadeDemo {

public static void main(String[] args) {

new HomeTheaterFacade(new DVDPlayer(), new Projector()).watchMovie();

// 输出:投影仪打开 → DVD打开

}

}

10. 桥接模式(Bridge)

意图:分离抽象与实现,使两者可独立变化。

特点:

解决抽象与实现的多对多继承问题(避免类爆炸);

抽象层与实现层通过组合关联,而非继承;

适合跨维度扩展场景(如“形状”与“颜色”)。

实现要点:

抽象类持有实现接口的引用;

抽象类的方法通过实现接口完成。

// 实现接口(颜色)

interface Color { void apply(); }

class Red implements Color { @Override public void apply() { System.out.println("红色"); } }

// 抽象类(形状)

abstract class Shape {

protected Color color;

public Shape(Color color) { this.color = color; }

abstract void draw();

}

// 具体抽象(圆形)

class Circle extends Shape {

public Circle(Color color) { super(color); }

@Override void draw() {

System.out.print("画圆形,颜色:");

color.apply();

}

}

// 使用

public class BridgeDemo {

public static void main(String[] args) {

new Circle(new Red()).draw(); // 输出:画圆形,颜色:红色

}

}

11. 组合模式(Composite)

意图:将对象组合成树形结构,统一处理单个对象和组合对象。

特点:

树形结构中,叶子节点与组合节点统一接口;

支持递归遍历(如文件系统的文件与文件夹);

客户端无需区分叶子与组合,操作一致。

实现要点:

抽象组件定义统一接口;

组合节点持有子组件列表,实现添加/删除/遍历。

// 抽象组件

interface Component {

void operation();

void add(Component c);

}

// 叶子节点(文件)

class File implements Component {

private String name;

public File(String name) { this.name = name; }

@Override public void operation() { System.out.println("文件:" + name); }

@Override public void add(Component c) {} // 叶子不支持添加

}

// 组合节点(文件夹)

class Folder implements Component {

private List children = new ArrayList<>();

private String name;

public Folder(String name) { this.name = name; }

@Override public void operation() {

System.out.println("文件夹:" + name);

children.forEach(Component::operation);

}

@Override public void add(Component c) { children.add(c); }

}

// 使用

public class CompositeDemo {

public static void main(String[] args) {

Folder root = new Folder("根目录");

root.add(new File("a.txt"));

root.operation(); // 输出:文件夹:根目录 → 文件:a.txt

}

}

12. 享元模式(Flyweight)

意图:共享细粒度对象,减少内存消耗。

特点:

区分“内部状态”(共享,如颜色)和“外部状态”(非共享,如位置);

通过享元池管理共享对象,避免重复创建;

适合对象数量多、重复度高的场景(如围棋棋子)。

实现要点:

享元工厂负责创建和缓存享元对象;

外部状态通过方法参数传入。

// 享元接口

interface Shape { void draw(int x, int y); }

// 具体享元(圆形)

class Circle implements Shape {

private String color; // 内部状态

public Circle(String color) { this.color = color; }

@Override public void draw(int x, int y) { // 外部状态

System.out.println("圆形(" + color + ") at (" + x + "," + y + ")");

}

}

// 享元工厂

class ShapeFactory {

private static final Map circles = new HashMap<>();

public static Shape getCircle(String color) {

return circles.computeIfAbsent(color, k -> {

System.out.println("创建" + color + "圆形");

return new Circle(color);

});

}

}

// 使用

public class FlyweightDemo {

public static void main(String[] args) {

Shape red1 = ShapeFactory.getCircle("红色");

Shape red2 = ShapeFactory.getCircle("红色"); // 复用

red1.draw(10, 20); // 圆形(红色) at (10,20)

}

}

三、行为型模式(11种)

关注对象间的通信、职责分配和行为交互。

13. 策略模式(Strategy)

意图:定义算法族,使其可互换,客户端可动态选择。

特点:

算法独立封装,易于扩展(新增策略只需实现接口);

解决“if-else”过多导致的代码臃肿;

客户端需知道所有策略类。

实现要点:

策略接口定义算法方法;

上下文持有策略引用,动态切换策略。

// 策略接口

interface Payment { void pay(int amount); }

// 具体策略(支付宝)

class Alipay implements Payment {

@Override public void pay(int amount) { System.out.println("支付宝支付:" + amount); }

}

// 上下文

class ShoppingCart {

private Payment payment;

public void setPayment(Payment payment) { this.payment = payment; }

public void checkout(int amount) { payment.pay(amount); }

}

// 使用

public class StrategyDemo {

public static void main(String[] args) {

ShoppingCart cart = new ShoppingCart();

cart.setPayment(new Alipay());

cart.checkout(100); // 输出:支付宝支付:100

}

}

14. 模板方法模式(Template Method)

意图:定义算法骨架,子类实现具体步骤。

特点:

固定流程,灵活定制步骤(如游戏的初始化→开始→结束);

父类调用子类方法(好莱坞原则:“别找我,我找你”);

符合开闭原则(扩展步骤而非修改骨架)。

实现要点:

抽象父类定义模板方法(包含固定步骤);

抽象方法由子类实现具体逻辑。

// 抽象模板

abstract class Game {

abstract void initialize();

abstract void start();

// 模板方法(固定流程)

public final void play() {

initialize();

start();

}

}

// 具体实现(足球)

class Football extends Game {

@Override void initialize() { System.out.println("足球初始化"); }

@Override void start() { System.out.println("足球开始"); }

}

// 使用

public class TemplateDemo {

public static void main(String[] args) {

new Football().play(); // 输出:足球初始化 → 足球开始

}

}

15. 观察者模式(Observer)

意图:对象间一对多依赖,当一个对象变化时通知所有依赖者。

特点:

松耦合:主题无需知道观察者细节;

支持动态添加/移除观察者;

适合事件驱动场景(如GUI事件、消息通知)。

实现要点:

主题维护观察者列表,提供注册/移除/通知方法;

观察者实现更新接口,接收主题通知。

// 主题接口

interface Subject {

void register(Observer o);

void notifyObservers(String msg);

}

// 观察者接口

interface Observer { void update(String msg); }

// 具体主题(公众号)

class WechatSubject implements Subject {

private List observers = new ArrayList<>();

@Override public void register(Observer o) { observers.add(o); }

@Override public void notifyObservers(String msg) {

observers.forEach(o -> o.update(msg));

}

}

// 具体观察者(用户)

class User implements Observer {

private String name;

public User(String name) { this.name = name; }

@Override public void update(String msg) {

System.out.println(name + "收到:" + msg);

}

}

// 使用

public class ObserverDemo {

public static void main(String[] args) {

WechatSubject subject = new WechatSubject();

subject.register(new User("张三"));

subject.notifyObservers("新文章发布"); // 张三收到:新文章发布

}

}

16. 迭代器模式(Iterator)

意图:提供遍历集合的统一接口,无需暴露内部结构。

特点:

客户端无需关心集合类型(列表、树等),通过迭代器遍历;

支持多种遍历方式(正向、反向);

符合单一职责原则(集合负责存储,迭代器负责遍历)。

实现要点:

迭代器接口定义hasNext()和next()方法;

集合提供获取迭代器的方法。

// 迭代器接口

interface Iterator {

boolean hasNext();

Object next();

}

// 集合接口

interface Container { Iterator getIterator(); }

// 具体集合(名字列表)

class NameContainer implements Container {

private String[] names = {"A", "B", "C"};

@Override public Iterator getIterator() {

return new NameIterator();

}

private class NameIterator implements Iterator {

int index = 0;

@Override public boolean hasNext() { return index < names.length; }

@Override public Object next() { return names[index++]; }

}

}

// 使用

public class IteratorDemo {

public static void main(String[] args) {

Container container = new NameContainer();

Iterator it = container.getIterator();

while (it.hasNext()) { System.out.println(it.next()); } // A、B、C

}

}

17. 责任链模式(Chain of Responsibility)

意图:将请求沿处理链传递,直到被处理。

特点:

发送者与接收者解耦,无需知道谁处理请求;

可动态调整链结构(如审批流程:组长→经理→总监);

可能导致请求未被处理。

实现要点:

处理器持有下一个处理器引用;

每个处理器判断是否处理请求,否则传递给下一个。

// 抽象处理器

abstract class Handler {

protected Handler next;

public void setNext(Handler next) { this.next = next; }

abstract void handle(int request);

}

// 处理1-10

class Handler1 extends Handler {

@Override void handle(int request) {

if (request <= 10) System.out.println("Handler1处理:" + request);

else if (next != null) next.handle(request);

}

}

// 处理11-20

class Handler2 extends Handler {

@Override void handle(int request) {

if (request <= 20) System.out.println("Handler2处理:" + request);

else if (next != null) next.handle(request);

}

}

// 使用

public class ChainDemo {

public static void main(String[] args) {

Handler h1 = new Handler1();

Handler h2 = new Handler2();

h1.setNext(h2);

h1.handle(5); // Handler1处理:5

h1.handle(15); // Handler2处理:15

}

}

18. 命令模式(Command)

意图:将请求封装为对象,使请求可参数化、队列化或撤销。

特点:

解耦请求发送者与接收者(如遥控器与灯);

支持命令排队、日志记录、事务回滚;

新增命令只需实现接口,扩展性好。

实现要点:

命令接口定义execute()方法;

具体命令持有接收者引用,调用其方法。

// 命令接口

interface Command { void execute(); }

// 接收者(灯)

class Light {

public void on() { System.out.println("灯亮"); }

}

// 具体命令(开灯)

class LightOnCommand implements Command {

private Light light;

public LightOnCommand(Light light) { this.light = light; }

@Override public void execute() { light.on(); }

}

// 调用者(遥控器)

class Remote {

private Command command;

public void setCommand(Command command) { this.command = command; }

public void press() { command.execute(); }

}

// 使用

public class CommandDemo {

public static void main(String[] args) {

Remote remote = new Remote();

remote.setCommand(new LightOnCommand(new Light()));

remote.press(); // 输出:灯亮

}

}

19. 备忘录模式(Memento)

意图:保存对象状态,以便后续恢复。

特点:

封装状态存储细节,原发器无需暴露内部状态;

适合游戏存档、编辑器撤销等场景;

需平衡内存开销(过多快照占用资源)。

实现要点:

备忘录存储原发器状态;

管理者负责保存和恢复备忘录。

// 备忘录

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 Memento save() { return new Memento(state); }

public void restore(Memento m) { state = m.getState(); }

}

// 管理者

class CareTaker {

private Memento memento;

public void save(Memento m) { memento = m; }

public Memento get() { return memento; }

}

// 使用

public class MementoDemo {

public static void main(String[] args) {

Originator o = new Originator();

CareTaker c = new CareTaker();

o.setState("状态1");

c.save(o.save()); // 保存

o.setState("状态2");

o.restore(c.get()); // 恢复为状态1

}

}

20. 状态模式(State)

意图:允许对象在内部状态变化时改变行为,类似状态机。

特点:

将状态逻辑封装到不同状态类,避免“if-else”堆砌;

状态转换清晰,可由状态类或上下文控制;

适合状态较多且转换复杂的场景(如订单状态)。

实现要点:

状态接口定义行为方法;

上下文持有当前状态,委托状态对象处理行为。

// 状态接口

interface State { void doAction(Context context); }

// 具体状态(开启)

class StartState implements State {

@Override public void doAction(Context context) {

System.out.println("系统开启");

context.setState(this);

}

}

// 上下文

class Context {

private State state;

public void setState(State state) { this.state = state; }

}

// 使用

public class StateDemo {

public static void main(String[] args) {

Context context = new Context();

new StartState().doAction(context); // 输出:系统开启

}

}

21. 访问者模式(Visitor)

意图:在不修改对象结构的前提下,为对象添加新操作。

特点:

分离“数据结构”与“操作行为”,新操作只需新增访问者;

适合数据结构稳定但操作多变的场景(如报表统计);

修改结构需修改所有访问者,灵活性低。

实现要点:

元素接口定义accept(Visitor)方法;

访问者接口定义对每个元素的操作方法。

// 元素接口

interface Element { void accept(Visitor v); }

// 具体元素(员工A)

class EmployeeA implements Element {

@Override public void accept(Visitor v) { v.visit(this); }

}

// 访问者接口

interface Visitor { void visit(EmployeeA a); }

// 具体访问者(计算工资)

class SalaryVisitor implements Visitor {

@Override public void visit(EmployeeA a) {

System.out.println("计算员工A工资");

}

}

// 使用

public class VisitorDemo {

public static void main(String[] args) {

Element e = new EmployeeA();

e.accept(new SalaryVisitor()); // 输出:计算员工A工资

}

}

22. 中介者模式(Mediator)

意图:用中介者封装对象间的交互,减少直接依赖。

特点:

将网状依赖转为星状依赖,降低复杂度;

集中管理交互逻辑,便于维护;

中介者可能成为“上帝类”,需避免逻辑过重。

实现要点:

中介者接口定义交互方法;

同事类持有中介者引用,通过中介者通信。

// 中介者接口

interface Mediator { void send(String msg, Colleague c); }

// 同事类

abstract class Colleague {

protected Mediator mediator;

public Colleague(Mediator m) { mediator = m; }

}

// 具体同事(用户1)

class User1 extends Colleague {

public User1(Mediator m) { super(m); }

public void send(String msg) { mediator.send(msg, this); }

public void receive(String msg) { System.out.println("User1收到:" + msg); }

}

// 具体中介者(聊天室)

class ChatMediator implements Mediator {

private User1 u1;

private User2 u2;

@Override public void send(String msg, Colleague c) {

if (c == u1) u2.receive(msg);

else u1.receive(msg);

}

}

// 使用

public class MediatorDemo {

public static void main(String[] args) {

Mediator m = new ChatMediator();

User1 u1 = new User1(m);

User2 u2 = new User2(m);

u1.send("你好"); // User2收到:你好

}

}

23. 解释器模式(Interpreter)

意图:定义语言语法的解释器,用于解析特定格式的语句。

特点:

适合简单语法(如正则表达式、表达式计算);

语法复杂时会导致类爆炸(如SQL解析);

可扩展新语法规则。

实现要点:

抽象表达式定义解释方法;

终结符表达式处理基本语法单元,非终结符表达式处理组合语法。

// 抽象表达式

interface Expression { boolean interpret(String context); }

// 终结符表达式(匹配单个字符)

class TerminalExpression implements Expression {

private String data;

public TerminalExpression(String data) { this.data = data; }

@Override public boolean interpret(String context) {

return context.contains(data);

}

}

// 非终结符表达式(或运算)

class OrExpression implements Expression {

private Expression e1, e2;

public OrExpression(Expression e1, Expression e2) {

this.e1 = e1;

this.e2 = e2;

}

@Override public boolean interpret(String context) {

return e1.interpret(context) || e2.interpret(context);

}

}

// 使用

public class InterpreterDemo {

public static void main(String[] args) {

Expression expr = new OrExpression(new TerminalExpression("a"), new TerminalExpression("b"));

System.out.println(expr.interpret("abc")); // true(含a)

}

}

总结

设计模式是解决特定问题的成熟方案,核心价值在于:

创建型:控制对象创建,降低耦合;

结构型:优化类/对象组合,实现复用;

行为型:规范对象交互,明确职责。

实际开发中需结合业务场景选择,避免过度设计。