易君召
发布于 2026-08-09 / 作者:易君召 / 2 阅读
0

GoF 23种软件设计模式和对应 Java 极简示例

设计模式分为创建型、结构型、行为型三大类,出自《GoF 设计模式》,一共 23 种,下面列出开发中高频使用的模式,附带作用、场景简单说明。

一、创建型模式(对象怎么创建)

负责对象实例化,解耦对象的创建与使用。

1. 单例模式 Singleton(双重检查锁)

保证一个类只有一个实例,提供全局访问点。

场景:配置管理器、连接池、日志对象。注意:多线程、序列化破坏单例问题。

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

2. 工厂方法 Factory Method

定义抽象工厂,子类决定实例化哪一个产品。

场景:同一类产品,多种实现,扩展产品只需新增子类。

// 产品
interface Product{
    void use();
}
class ProductA implements Product{
    @Override public void use() { System.out.println("使用产品A"); }
}

// 抽象工厂
abstract class Factory{
    public abstract Product createProduct();
}

// 具体工厂
class FactoryA extends Factory{
    @Override public Product createProduct() { return new ProductA(); }
}

// 使用
public class Demo {
    public static void main(String[] args) {
        Factory factory = new FactoryA();
        Product product = factory.createProduct();
        product.use();
    }
}

3. 抽象工厂 AbstractFactory

创建一组相关 / 相互依赖的对象家族。

场景:一套 UI 组件(按钮、输入框,适配 Windows/Mac)。

// 产品族A/B
interface Button{ void render(); }
class WinButton implements Button{ @Override public void render() {System.out.println("Windows按钮");} }
class MacButton implements Button{ @Override public void render() {System.out.println("Mac按钮");} }

interface TextBox{ void show(); }
class WinTextBox implements TextBox{ @Override public void show() {System.out.println("Windows输入框");} }
class MacTextBox implements TextBox{ @Override public void show() {System.out.println("Mac输入框");} }

//抽象工厂:生产一组产品
interface GuiFactory{
    Button createButton();
    TextBox createTextBox();
}

class WinGuiFactory implements GuiFactory{
    @Override public Button createButton() { return new WinButton(); }
    @Override public TextBox createTextBox() { return new WinTextBox(); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        GuiFactory factory = new WinGuiFactory();
        factory.createButton().render();
        factory.createTextBox().show();
    }
}

4. 建造者 Builder

分步构建复杂对象,同样构建过程得到不同表示。

场景:复杂对象组装,如 HTTP 请求对象、复杂 DTO。

//复杂对象
class Person{
    private String name;
    private int age;
    private String address;
    private Person(Builder builder){
        this.name = builder.name;
        this.age = builder.age;
        this.address = builder.address;
    }
    public static class Builder{
        private String name;
        private int age;
        private String address;
        public Builder name(String name){ this.name=name; return this; }
        public Builder age(int age){ this.age=age; return this; }
        public Builder address(String address){ this.address=address; return this; }
        public Person build(){ return new Person(this); }
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Person p = new Person.Builder().name("张三").age(20).address("南京").build();
    }
}

5. 原型模式 Prototype

通过克隆已有对象来创建新对象,而不是 new。

场景:对象创建成本高,大量相似对象;深浅拷贝问题。

class Sheep implements Cloneable{
    private String name;
    public Sheep(String name){ this.name=name; }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Demo{
    public static void main(String[] args) throws CloneNotSupportedException {
        Sheep s1 = new Sheep("小羊");
        Sheep s2 = (Sheep) s1.clone(); //克隆创建对象
    }
}

二、结构型模式(类 / 对象怎么组合)

把类、对象组装成更大的结构。

6. 适配器 Adapter(对象适配器)

把一个类接口转换成客户端期望的接口,做兼容适配。

场景:第三方 SDK 适配、新旧系统接口兼容。分对象适配器、类适配器。

//原有接口
class Adaptee{
    public void oldMethod(){ System.out.println("旧接口方法"); }
}
//目标接口
interface Target{
    void targetMethod();
}
//适配器包装旧对象
class Adapter implements Target{
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee){ this.adaptee=adaptee; }
    @Override public void targetMethod() {
        adaptee.oldMethod();
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Target t = new Adapter(new Adaptee());
        t.targetMethod();
    }
}

7. 桥接模式 Bridge

分离抽象与实现,两者可以独立变化。

场景:多维度变化,例如:形状 + 颜色,手机系统 + 软件。

//实现维度
interface Color{ void paint(); }
class Red implements Color{ @Override public void paint() {System.out.println("红色");} }
class Blue implements Color{ @Override public void paint() {System.out.println("蓝色");} }

//抽象维度
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); }
    @Override public void draw() {
        color.paint();
        System.out.println("画圆形");
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Shape shape = new Circle(new Red());
        shape.draw();
    }
}

8. 装饰器 Decorator

动态给对象增加职责,不修改原有代码。

场景:IO 流包装、增加日志 / 权限、动态增强功能。

interface Coffee{ double cost(); }
class SimpleCoffee implements Coffee{
    @Override public double cost() { return 10; }
}

//装饰器
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); }
    @Override public double cost() { return coffee.cost()+2; }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Coffee c = new MilkDecorator(new SimpleCoffee());
        System.out.println(c.cost());
    }
}

9. 组合模式 Composite(树形)

树形结构,统一对待单个对象和组合对象(叶子、容器)。

场景:目录文件树、组织部门树、菜单树。

//组件抽象
abstract class Node{
    protected String name;
    public Node(String name){ this.name=name; }
    public abstract void show();
}

//叶子节点
class Leaf extends Node{
    public Leaf(String name) { super(name); }
    @Override public void show() { System.out.println(name); }
}

//容器节点,可以包含子节点
import java.util.ArrayList;
class Composite extends Node{
    private ArrayList<Node> children = new ArrayList<>();
    public Composite(String name) { super(name); }
    public void add(Node node){ children.add(node); }
    @Override public void show() {
        System.out.println("["+name+"]");
        for(Node n : children){ n.show(); }
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Composite root = new Composite("根目录");
        root.add(new Leaf("文件1"));
        Composite sub = new Composite("子文件夹");
        sub.add(new Leaf("文件2"));
        root.add(sub);
        root.show();
    }
}

10. 外观模式 Facade

提供一个高层统一入口,封装复杂子系统,简化调用。

场景:复杂底层 SDK 封装,对外只暴露简单接口。

//多个复杂子系统
class SubSystemA{ public void a(){System.out.println("子系统A");} }
class SubSystemB{ public void b(){System.out.println("子系统B");} }

//外观,对外统一简单接口
class Facade{
    private SubSystemA a = new SubSystemA();
    private SubSystemB b = new SubSystemB();
    public void doAll(){
        a.a();
        b.b();
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.doAll(); //调用方不用关心内部多个子系统
    }
}

11. 享元模式 Flyweight

共享细粒度对象,减少大量对象内存开销。

场景:大量重复对象,比如字符、棋子对象。

import java.util.HashMap;
//享元对象
interface Chess{ void show(String pos); }
class BlackChess implements Chess{
    @Override public void show(String pos) { System.out.println("黑棋:"+pos); }
}
class WhiteChess implements Chess{
    @Override public void show(String pos) { System.out.println("白棋:"+pos); }
}

//享元工厂,做对象缓存
class ChessFactory{
    private HashMap<String,Chess> pool = new HashMap<>();
    public Chess getChess(String color){
        if(!pool.containsKey(color)){
            if("black".equals(color)) pool.put(color,new BlackChess());
            else pool.put(color,new WhiteChess());
        }
        return pool.get(color);
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        ChessFactory factory = new ChessFactory();
        Chess c1 = factory.getChess("black");
        Chess c2 = factory.getChess("black");
        System.out.println(c1==c2); //true,复用同一个对象
    }
}

12. 代理模式 Proxy(静态代理)

提供代理对象控制对真实对象的访问。

场景:静态代理、JDK 动态代理、CGLIB;AOP、远程代理、虚拟代理。

interface Subject{ void request(); }
class RealSubject implements Subject{
    @Override public void request() { System.out.println("真实业务执行"); }
}

//代理类
class Proxy implements Subject{
    private RealSubject realSubject;
    @Override public void request() {
        System.out.println("代理前置增强");
        if(realSubject==null) realSubject=new RealSubject();
        realSubject.request();
        System.out.println("代理后置增强");
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}

三、行为型模式(对象之间怎么交互)

处理对象通信、职责分配、算法封装。

13. 策略模式 Strategy

封装一组算法,可以互相替换,算法变化不影响调用方。

场景:多种计算规则、支付方式、排序算法。

//策略接口
interface Strategy{ int calc(int a,int b); }
class AddStrategy implements Strategy{ @Override public int calc(int a, int b) {return a+b;} }
class SubStrategy implements Strategy{ @Override public int calc(int a, int b) {return a-b;} }

//上下文持有策略
class Context{
    private Strategy strategy;
    public Context(Strategy s){ this.strategy=s; }
    public int execute(int a,int b){ return strategy.calc(a,b); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Context ctx = new Context(new AddStrategy());
        System.out.println(ctx.execute(1,2));
    }
}

14. 模板方法 Template Method

父类定义算法骨架,子类重写部分步骤。

场景:框架基类,流程固定,部分逻辑由业务实现。

abstract class AbstractTemplate{
    //固定骨架
    public final void template(){
        step1();
        step2();
        step3();
    }
    void step1(){ System.out.println("通用步骤1"); }
    abstract void step2(); //子类实现
    void step3(){ System.out.println("通用步骤3"); }
}

class Concrete extends AbstractTemplate{
    @Override void step2() { System.out.println("子类自定义步骤2"); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        AbstractTemplate t = new Concrete();
        t.template();
    }
}

15. 观察者 Observer(发布订阅)

一对多,主题通知所有观察者。

场景:事件监听、消息通知、Spring 事件驱动。

import java.util.ArrayList;
//观察者
interface Observer{ void update(String msg); }
class UserObserver implements Observer{
    @Override public void update(String msg) { System.out.println("收到消息:"+msg); }
}

//被观察者主题
class Subject{
    private ArrayList<Observer> obs = new ArrayList<>();
    public void addObserver(Observer o){ obs.add(o); }
    public void notifyAllObservers(String msg){
        for(Observer o:obs) o.update(msg);
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Subject subject = new Subject();
        subject.addObserver(new UserObserver());
        subject.notifyAllObservers("事件来了");
    }
}

16. 迭代器 Iterator

遍历集合,不暴露集合内部结构。

场景:各种集合遍历。

//简单自定义迭代器
interface MyIterator{ boolean hasNext(); Object next(); }

interface Aggregate{ MyIterator getIterator(); }

class NameAggregate implements Aggregate{
    private String[] arr;
    public NameAggregate(String[] arr){ this.arr=arr; }
    @Override public MyIterator getIterator() {
        return new MyIterator(){
            private int index=0;
            @Override public boolean hasNext() { return index < arr.length; }
            @Override public Object next() { return arr[index++]; }
        };
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        String[] names = {"A","B","C"};
        Aggregate agg = new NameAggregate(names);
        MyIterator it = agg.getIterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

17. 责任链 Chain of Responsibility

请求沿着处理链传递,每个对象决定处理或传给下一个。

场景:过滤器、拦截器、审批流程、Spring Filter。

abstract class Handler{
    protected Handler next;
    public void setNext(Handler next){ this.next=next; }
    public abstract void handle(int request);
}

class HandlerA extends Handler{
    @Override public void handle(int request) {
        if(request<10){
            System.out.println("A处理:"+request);
        }else if(next!=null){
            next.handle(request);
        }
    }
}
class HandlerB extends Handler{
    @Override public void handle(int request) {
        System.out.println("B处理:"+request);
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Handler h1=new HandlerA();
        Handler h2=new HandlerB();
        h1.setNext(h2);
        h1.handle(20);
    }
}

18. 命令模式 Command

把请求封装成对象,支持撤销、排队、日志。

场景:操作回滚、任务队列。

interface Command{ void execute(); }
class LightReceiver{ public void on(){ System.out.println("灯打开"); } }

class LightOnCommand implements Command{
    private LightReceiver receiver;
    public LightOnCommand(LightReceiver r){ receiver=r; }
    @Override public void execute() { receiver.on(); }
}

//调用者
class Invoker{
    private Command cmd;
    public Invoker(Command c){ cmd=c; }
    public void trigger(){ cmd.execute(); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Invoker invoker = new Invoker(new LightOnCommand(new LightReceiver()));
        invoker.trigger();
    }
}

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 s){ state=s; }
    public Memento saveMemento(){ return new Memento(state); }
    public void restore(Memento m){ state=m.getState(); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Originator o = new Originator();
        o.setState("状态1");
        Memento m = o.saveMemento();
        o.setState("状态2");
        o.restore(m); //恢复旧状态
    }
}

20. 中介者 Mediator

用中介对象封装多对象交互,减少对象之间耦合。

场景:多组件交互,聊天室。

import java.util.ArrayList;
abstract class Colleague{
    protected Mediator mediator;
    public Colleague(Mediator m){ mediator=m; }
}

class UserColleague extends Colleague{
    private String name;
    public UserColleague(Mediator m,String name) { super(m); this.name=name; }
    public void sendMsg(String msg){ mediator.send(msg,this); }
    public void receive(String msg){ System.out.println(name+"收到:"+msg); }
}

interface Mediator{ void send(String msg,UserColleague sender); }
class ChatMediator implements Mediator{
    private ArrayList<UserColleague> list=new ArrayList<>();
    public void addUser(UserColleague u){ list.add(u); }
    @Override public void send(String msg, UserColleague sender) {
        for(UserColleague u:list){
            if(u!=sender) u.receive(msg);
        }
    }
}

//使用
public class Demo{
    public static void main(String[] args) {
        ChatMediator chat = new ChatMediator();
        UserColleague u1=new UserColleague(chat,"甲");
        UserColleague u2=new UserColleague(chat,"乙");
        chat.addUser(u1); chat.addUser(u2);
        u1.sendMsg("hello");
    }
}

21. 状态模式 State

对象内部状态改变时改变行为,看起来像改变了类。

场景:订单状态、工单状态机。

interface State{ void handle(); }
class StateA implements State{ @Override public void handle() {System.out.println("状态A处理");} }
class StateB implements State{ @Override public void handle() {System.out.println("状态B处理");} }

class ContextState{
    private State state;
    public void setState(State s){ state=s; }
    public void request(){ state.handle(); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        ContextState ctx = new ContextState();
        ctx.setState(new StateA());
        ctx.request();
        ctx.setState(new StateB());
        ctx.request();
    }
}

22. 访问者 Visitor

对一组对象做不同操作,不修改对象类本身。

场景:数据结构稳定,需要新增多种操作。

//元素
interface Element{ void accept(Visitor v); }
class ElementA implements Element{
    @Override public void accept(Visitor v) { v.visit(this); }
}
class ElementB implements Element{
    @Override public void accept(Visitor v) { v.visit(this); }
}

//访问者
interface Visitor{
    void visit(ElementA a);
    void visit(ElementB b);
}
class ConcreteVisitor implements Visitor{
    @Override public void visit(ElementA a) { System.out.println("访问A"); }
    @Override public void visit(ElementB b) { System.out.println("访问B"); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Element e = new ElementA();
        e.accept(new ConcreteVisitor());
    }
}

23. 解释器 Interpreter(很少业务使用)

定义文法,解释语言表达式,实际项目很少用。

//简单解释器,数字表达式
interface Expression{ int interpret(); }
class NumExpression implements Expression{
    private int val;
    public NumExpression(int v){ val=v; }
    @Override public int interpret() { return val; }
}
class AddExpression implements Expression{
    private Expression left,right;
    public AddExpression(Expression l,Expression r){ left=l;right=r; }
    @Override public int interpret() { return left.interpret()+right.interpret(); }
}

//使用
public class Demo{
    public static void main(String[] args) {
        Expression exp = new AddExpression(new NumExpression(1),new NumExpression(2));
        System.out.println(exp.interpret());
    }
}

本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。

原文链接 https://www.yijunzhao.cn/archives/gof-23-design-patterns-java-minimal-examples

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/