常见设计模式简介

创建型

工厂模式

定义一个工厂接口,让子类去决定具体创建哪种产品

产品接口A+具体产品实现产品接口A

抽象类工厂B,里面的抽象方法是创建产品+具体工厂继承工厂B,创建产品的方法里按照想要创建的产品来new对象

客户端使用 工厂B=具体工厂,工厂B.创建产品,产品.具体方法。

也就是直接用工厂就能创建出不同的产品,只需要直接new的时候是new哪个具体工厂就行

解耦客户端和具体产品

易于扩展新产品

java 复制代码
// 产品接口
interface Product {
    void use();
}

// 具体产品
class ConcreteProductA implements Product {
    public void use() { System.out.println("使用产品A"); }
}

class ConcreteProductB implements Product {
    public void use() { System.out.println("使用产品B"); }
}

// 工厂接口
abstract class Factory {
    abstract Product createProduct();
}

// 具体工厂
class FactoryA extends Factory {
    Product createProduct() { return new ConcreteProductA(); }
}

class FactoryB extends Factory {
    Product createProduct() { return new ConcreteProductB(); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Factory factory = new FactoryA();
        Product product = factory.createProduct();
        product.use(); // 输出:使用产品A
    }
}

抽象工厂

和工厂差不多,只是上面是一个产品,这里是一族产品。通过抽象工厂接口动态创建同一产品族的一整套产品。

注意工厂,在工厂方法中用的抽象类,在抽象工厂中用的接口。因为单个产品可以实现一些默认方法,抽象工厂更灵活直接用接口定义需要实现哪些方法。

java 复制代码
interface Button { void click(); }
interface TextField { void display(); }

// 具体产品族:Windows
class WinButton implements Button { public void click() { System.out.println("Windows 按钮点击"); } }
class WinTextField implements TextField { public void display() { System.out.println("Windows 文本框显示"); } }

// 具体产品族:Mac
class MacButton implements Button { public void click() { System.out.println("Mac 按钮点击"); } }
class MacTextField implements TextField { public void display() { System.out.println("Mac 文本框显示"); } }

// 抽象工厂
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂
class WinFactory implements GUIFactory {
    public Button createButton() { return new WinButton(); }
    public TextField createTextField() { return new WinTextField(); }
}

class MacFactory implements GUIFactory {
    public Button createButton() { return new MacButton(); }
    public TextField createTextField() { return new MacTextField(); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        GUIFactory factory = new WinFactory(); // 可以换成 MacFactory
        Button btn = factory.createButton();
        TextField tf = factory.createTextField();
        btn.click();
        tf.display();
    }
}

生成器

客户端 → 调用 Director

Director → 按顺序调用 Builder 各个构建方法(Director = 流程封装者,可选,不是必须)

Builder → 构建每个部件

Builder → 返回最终 Product

客户端 → 得到完整产品,无需关心内部步骤

java 复制代码
class Product {
    private String partA;
    private String partB;
    public void setPartA(String partA) { this.partA = partA; }
    public void setPartB(String partB) { this.partB = partB; }
    public void show() { System.out.println("PartA: "+partA+", PartB: "+partB); }
}

// 抽象生成器
abstract class Builder {
    abstract void buildPartA();
    abstract void buildPartB();
    abstract Product getResult();
}

// 具体生成器
class ConcreteBuilder extends Builder {
    private Product product = new Product();
    void buildPartA() { product.setPartA("组件A"); }
    void buildPartB() { product.setPartB("组件B"); }
    Product getResult() { return product; }
}

// 指挥者
class Director {
    private Builder builder;
    public Director(Builder builder) { this.builder = builder; }
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        return builder.getResult();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show(); // 输出 PartA: 组件A, PartB: 组件B
    }
}

原型

通过复制已有的对象来创建新对象,而不是通过 new 去实例化

java 复制代码
interface Prototype extends Cloneable {
    Prototype clone();
}

// 具体原型
class ConcretePrototype implements Prototype {
    private String field;
    public ConcretePrototype(String field) { this.field = field; }
    public void setField(String field) { this.field = field; }
    public String getField() { return field; }

    @Override
    public Prototype clone() {
        try {
            return (ConcretePrototype) super.clone(); // 浅拷贝
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("原型对象");
        ConcretePrototype copy = (ConcretePrototype) prototype.clone();
        copy.setField("克隆对象");
        System.out.println(prototype.getField()); // 输出:原型对象
        System.out.println(copy.getField());      // 输出:克隆对象
    }
}

单例

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

java 复制代码
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;
    }
}
java 复制代码
class Singleton {
    private Singleton() {}
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

结构型

适配器

Target(目标接口)

  • 客户端期待的接口

Adaptee(适配者)

  • 已有的接口或类,需要适配

Adapter(适配器)

  • 将 Adaptee 转换为 Target 接口
  • 客户端通过 Adapter 调用 Adaptee

将一个类的接口转换成客户端期望的接口,使原本因接口不兼容而无法一起工作的类能够协同工作

java 复制代码
interface MediaPlayer {        // Target
    void play(String audioType, String fileName);
}

class Mp3Player implements MediaPlayer { // 已有类,直接支持 mp3
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("mp3")) {
            System.out.println("播放 mp3 文件:" + fileName);
        }
    }
}

// 适配者:支持 vlc 格式
class VlcPlayer {
    public void playVlc(String fileName) {
        System.out.println("播放 vlc 文件:" + fileName);
    }
}

// 适配器:把 VlcPlayer 适配成 MediaPlayer
class MediaAdapter implements MediaPlayer {
    private VlcPlayer vlcPlayer;
    public MediaAdapter(String audioType) {
        if(audioType.equalsIgnoreCase("vlc")) {
            vlcPlayer = new VlcPlayer();
        }
    }
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("vlc")) {
            vlcPlayer.playVlc(fileName);
        }
    }
}

// 客户端
public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("mp3")) {
            System.out.println("播放 mp3 文件:" + fileName);
        } else if(audioType.equalsIgnoreCase("vlc")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("格式不支持:" + audioType);
        }
    }
}

桥接器

  1. 问题来源**

假设你要设计一个绘图系统,有两类变化维度:

  1. 形状(Shape):圆形、方形、三角形......
  2. 颜色/绘制方式(DrawAPI):红色、绿色、蓝色、虚线、实线......

如果你用传统继承:

  • 你可能会写 RedCircleGreenCircleRedSquareGreenSquare......
  • 这样类数量 会爆炸(形状 × 绘制方式 = 很多类)
  1. 桥接模式的目的**

桥接模式就是 解耦两个变化维度

  • 抽象部分(Shape):定义形状
  • 实现部分(DrawAPI):定义颜色或绘制方式
  • 桥接:Shape 持有 DrawAPI 的引用,通过它去绘制

这样就可以自由组合:

  • 圆形 + 红色
  • 圆形 + 绿色
  • 方形 + 红色
  • 方形 + 绿色

而不需要为每种组合写一个类。

桥接模式 = 把"抽象"和"实现"分开,让两边独立扩展,自由组合

  • 抽象(Shape)和实现(DrawAPI)都可以独立增加新类

  • 不用继承堆出大量子类

  • 抽象 = "形状工厂"

  • 实现 = "画笔类型"

  • 桥接 = "工厂拿着画笔去画"

  • 好处:你可以随便换工厂或画笔组合,不用写新类


💡 一句话理解

桥接模式就是 解决两个变化维度的组合问题,让它们独立扩展,不爆炸类

java 复制代码
// 实现部分接口:绘制方式
interface DrawAPI {
    void draw(String shapeName, int x, int y);
}

// 具体实现1:红色绘制
class RedDraw implements DrawAPI {
    public void draw(String shapeName, int x, int y) {
        System.out.println("用红色画 " + shapeName + " 在 (" + x + "," + y + ")");
    }
}

// 具体实现2:绿色绘制
class GreenDraw implements DrawAPI {
    public void draw(String shapeName, int x, int y) {
        System.out.println("用绿色画 " + shapeName + " 在 (" + x + "," + y + ")");
    }
}

// 抽象部分:形状
abstract class Shape {
    protected DrawAPI drawAPI; // 桥接
    protected String name;
    public Shape(String name, DrawAPI drawAPI) {
        this.name = name;
        this.drawAPI = drawAPI;
    }
    abstract void draw(int x, int y);
}

// 扩展抽象类1:圆形
class Circle extends Shape {
    public Circle(DrawAPI drawAPI) {
        super("圆形", drawAPI);
    }
    public void draw(int x, int y) {
        drawAPI.draw(name, x, y);
    }
}

// 扩展抽象类2:方形
class Square extends Shape {
    public Square(DrawAPI drawAPI) {
        super("方形", drawAPI);
    }
    public void draw(int x, int y) {
        drawAPI.draw(name, x, y);
    }
}

// 客户端演示
public class Client {
    public static void main(String[] args) {
        // 红色圆形
        Shape redCircle = new Circle(new RedDraw());
        redCircle.draw(10, 20);

        // 绿色圆形
        Shape greenCircle = new Circle(new GreenDraw());
        greenCircle.draw(15, 25);

        // 红色方形
        Shape redSquare = new Square(new RedDraw());
        redSquare.draw(5, 5);

        // 绿色方形
        Shape greenSquare = new Square(new GreenDraw());
        greenSquare.draw(12, 8);
    }
}

组合

组合模式 = 把单个对象和组合对象用同一个接口表示 ,让客户端 一致地处理单个对象和组合对象

优点:

  • 客户端操作统一
  • 支持树形结构递归
  • 易扩展新类型
java 复制代码
import java.util.*;

// 组件接口
interface Component {
    void showName();
}

// 叶子节点:文件
class FileLeaf implements Component {
    private String name;
    public FileLeaf(String name) { this.name = name; }
    public void showName() {
        System.out.println("文件: " + name);
    }
}

// 组合节点:文件夹
class FolderComposite implements Component {
    private String name;
    private List<Component> children = new ArrayList<>();
    public FolderComposite(String name) { this.name = name; }
    public void add(Component c) { children.add(c); }
    public void remove(Component c) { children.remove(c); }
    public void showName() {
        System.out.println("文件夹: " + name);
        for(Component c : children) {
            c.showName(); // 递归调用
        }
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Component file1 = new FileLeaf("file1.txt");
        Component file2 = new FileLeaf("file2.txt");

        FolderComposite folder1 = new FolderComposite("folder1");
        folder1.add(file1);
        folder1.add(file2);

        Component file3 = new FileLeaf("file3.txt");

        FolderComposite root = new FolderComposite("root");
        root.add(folder1);
        root.add(file3);

        root.showName();
    }
}

装饰器

装饰模式 = 动态给对象添加功能,而不改原类

Component(组件接口) = 原始对象的接口(咖啡、饮品)

ConcreteComponent(具体组件) = 原始对象(SimpleCoffee)

Decorator(装饰类) = 持有 Component 引用,扩展功能

ConcreteDecorator(具体装饰) = 牛奶、糖、巧克力等

java 复制代码
interface Coffee {           // Component
    double cost();
    String getDescription();
}

// ConcreteComponent
class SimpleCoffee implements Coffee {
    public double cost() { return 5; }
    public String getDescription() { return "简单咖啡"; }
}

// Decorator
abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;
    public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; }
}

// ConcreteDecorator 1:加牛奶
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) { super(coffee); }
    public double cost() { return coffee.cost() + 2; }
    public String getDescription() { return coffee.getDescription() + " + 牛奶"; }
}

// ConcreteDecorator 2:加糖
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) { super(coffee); }
    public double cost() { return coffee.cost() + 1; }
    public String getDescription() { return coffee.getDescription() + " + 糖"; }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " ¥" + coffee.cost());

        coffee = new MilkDecorator(coffee);
        coffee = new SugarDecorator(coffee);
        System.out.println(coffee.getDescription() + " ¥" + coffee.cost());
    }
}

外观

  1. 核心问题**

假设你在做 家庭影院系统

  • 有多个子系统:DVD 播放器、音响、投影仪、灯光、空调......
  • 客户端想"看电影"
  • 如果客户端自己一个个去调用每个子系统的开关方法,太复杂

问题:客户端不想关心这么多细节,只想一个简单接口操作整个系统

  1. 外观模式的目的**

提供一个 统一的高层接口 ,让客户端 简单操作复杂子系统,降低耦合。

核心思想:

  • Facade(外观类) = 提供简单接口
  • Subsystem(子系统) = 具体复杂系统
  • 客户端只和 Facade 交互,不直接操作子系统
java 复制代码
class DVDPlayer {
    public void on() { System.out.println("DVD 打开"); }
    public void play(String movie) { System.out.println("播放电影:" + movie); }
    public void off() { System.out.println("DVD 关闭"); }
}

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

class SoundSystem {
    public void on() { System.out.println("音响打开"); }
    public void off() { System.out.println("音响关闭"); }
}

// 外观类
class HomeTheaterFacade {
    private DVDPlayer dvd;
    private Projector projector;
    private SoundSystem sound;

    public HomeTheaterFacade(DVDPlayer dvd, Projector projector, SoundSystem sound) {
        this.dvd = dvd;
        this.projector = projector;
        this.sound = sound;
    }

    public void watchMovie(String movie) {
        System.out.println("准备看电影...");
        dvd.on();
        dvd.play(movie);
        projector.on();
        sound.on();
    }

    public void endMovie() {
        System.out.println("结束电影...");
        dvd.off();
        projector.off();
        sound.off();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        DVDPlayer dvd = new DVDPlayer();
        Projector projector = new Projector();
        SoundSystem sound = new SoundSystem();

        HomeTheaterFacade theater = new HomeTheaterFacade(dvd, projector, sound);
        theater.watchMovie("阿凡达");
        System.out.println("----电影结束----");
        theater.endMovie();
    }
}

享元

共享对象,避免重复创建 ,把可共享部分和不可共享部分分离

核心思想:

  • Intrinsic state(内部状态,可共享):对象的共享部分,比如字符"a"的字体、形状
  • Extrinsic state(外部状态,不可共享):对象的上下文,比如位置、颜色
  • 享元工厂:统一管理共享对象,避免重复创建
java 复制代码
import java.util.*;

// 抽象享元
interface Glyph {
    void display(int x, int y); // 外部状态:位置
}

// 具体享元
class CharacterGlyph implements Glyph {
    private char character; // 内部状态:字符本身

    public CharacterGlyph(char character) {
        this.character = character;
    }

    public void display(int x, int y) {
        System.out.println("显示字符 '" + character + "' 在 (" + x + "," + y + ")");
    }
}

// 享元工厂
class GlyphFactory {
    private Map<Character, Glyph> pool = new HashMap<>();

    public Glyph getCharacter(char c) {
        if(!pool.containsKey(c)) {
            pool.put(c, new CharacterGlyph(c));
        }
        return pool.get(c);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        GlyphFactory factory = new GlyphFactory();

        // 文本 "HELLO"
        int x = 0;
        for(char c : "HELLO".toCharArray()) {
            Glyph glyph = factory.getCharacter(c);
            glyph.display(x, 0); // 位置不同,字符对象共享
            x += 1;
        }
    }
}

代理

代理模式 = 在真实对象前后加"代理",增加控制逻辑

java 复制代码
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);
        }
        System.out.println("代理操作前逻辑"); 
        realImage.display();                // 调用真实对象
        System.out.println("代理操作后逻辑");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");

        // 第一次显示,真实对象才会被创建
        image.display();
        System.out.println("---第二次显示---");
        // 第二次显示,不需要重新加载
        image.display();
    }
}

行为型

责任链

让多个对象都有机会处理请求,将请求沿着链传递,直到有对象处理它

核心思想:

  • Handler(处理者接口) = 定义处理请求方法和链的引用
  • ConcreteHandler(具体处理者) = 实现处理逻辑,决定是否处理或传给下一个
  • Client(客户端) = 只发起请求,不关心谁处理

请假审批

日志处理(debug/info/error 按级别处理)

事件处理(GUI 事件冒泡)

系统请求过滤(安全过滤器链

java 复制代码
abstract class Handler {
    protected Handler next; // 链上的下一个处理者

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

    public abstract void handleRequest(int days);
}

// 具体处理者1:班主任
class ClassTeacher extends Handler {
    public void handleRequest(int days) {
        if(days <= 2) {
            System.out.println("班主任批准请假 " + days + " 天");
        } else if(next != null) {
            next.handleRequest(days); // 转交下一个
        }
    }
}

// 具体处理者2:系主任
class DepartmentHead extends Handler {
    public void handleRequest(int days) {
        if(days <= 5) {
            System.out.println("系主任批准请假 " + days + " 天");
        } else if(next != null) {
            next.handleRequest(days);
        }
    }
}

// 具体处理者3:校长
class Principal extends Handler {
    public void handleRequest(int days) {
        System.out.println("校长批准请假 " + days + " 天");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Handler classTeacher = new ClassTeacher();
        Handler deptHead = new DepartmentHead();
        Handler principal = new Principal();

        // 设置责任链
        classTeacher.setNext(deptHead);
        deptHead.setNext(principal);

        // 发起请求
        int leaveDays1 = 1;
        classTeacher.handleRequest(leaveDays1); // 由班主任处理

        int leaveDays2 = 4;
        classTeacher.handleRequest(leaveDays2); // 班主任不处理,传给系主任

        int leaveDays3 = 10;
        classTeacher.handleRequest(leaveDays3); // 最终由校长处理
    }
}

命令

把"请求"抽象成对象,让调用者(Invoker)不用关心请求细节,提高系统灵活性和可扩展性.遥控器(Invoker)可以动态控制 任意设备

java 复制代码
// 命令接口
interface Command {
    void execute();
}

// 接收者1:灯
class Light {
    public void on() { System.out.println("灯打开"); }
    public void off() { System.out.println("灯关闭"); }
}

// 接收者2:空调
class AirCondition {
    public void on() { System.out.println("空调打开"); }
    public void off() { System.out.println("空调关闭"); }
}

// 具体命令1:开灯
class LightOnCommand implements Command {
    private Light light;
    public LightOnCommand(Light light) { this.light = light; }
    public void execute() { light.on(); }
}

// 具体命令2:关灯
class LightOffCommand implements Command {
    private Light light;
    public LightOffCommand(Light light) { this.light = light; }
    public void execute() { light.off(); }
}

// 具体命令3:开空调
class ACOnCommand implements Command {
    private AirCondition ac;
    public ACOnCommand(AirCondition ac) { this.ac = ac; }
    public void execute() { ac.on(); }
}

// 具体命令4:关空调
class ACOffCommand implements Command {
    private AirCondition ac;
    public ACOffCommand(AirCondition ac) { this.ac = ac; }
    public void execute() { ac.off(); }
}

// 调用者:遥控器
class RemoteControl {
    private Command slot;
    public void setCommand(Command command) { slot = command; }
    public void pressButton() { slot.execute(); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Light light = new Light();
        AirCondition ac = new AirCondition();

        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);
        Command acOn = new ACOnCommand(ac);
        Command acOff = new ACOffCommand(ac);

        RemoteControl remote = new RemoteControl();

        // 开灯
        remote.setCommand(lightOn);
        remote.pressButton();

        // 关灯
        remote.setCommand(lightOff);
        remote.pressButton();

        // 开空调
        remote.setCommand(acOn);
        remote.pressButton();

        // 关空调
        remote.setCommand(acOff);
        remote.pressButton();
    }
}

迭代器

提供一种 顺序访问集合元素的方式,而不暴露集合内部结构

Iterator(迭代器接口) = 提供访问元素的方法(hasNext()next()

ConcreteIterator(具体迭代器) = 实现遍历逻辑

Aggregate(聚合接口) = 提供创建迭代器方法

ConcreteAggregate(具体聚合) = 实现集合存储和迭代器创建

java 复制代码
import java.util.*;

// 迭代器接口
interface Iterator<E> {
    boolean hasNext();
    E next();
}

// 聚合接口
interface Aggregate<E> {
    Iterator<E> createIterator();
}

// 具体聚合:书架
class BookShelf implements Aggregate<String> {
    private List<String> books = new ArrayList<>();

    public void addBook(String book) {
        books.add(book);
    }

    public Iterator<String> createIterator() {
        return new BookShelfIterator(books);
    }
}

// 具体迭代器
class BookShelfIterator implements Iterator<String> {
    private List<String> books;
    private int index = 0;

    public BookShelfIterator(List<String> books) {
        this.books = books;
    }

    public boolean hasNext() {
        return index < books.size();
    }

    public String next() {
        return books.get(index++);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        BookShelf shelf = new BookShelf();
        shelf.addBook("Java 编程思想");
        shelf.addBook("Effective Java");
        shelf.addBook("算法导论");

        Iterator<String> iterator = shelf.createIterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

中介者

中介者模式 = 对象之间不直接通信,通过中介者协调

java 复制代码
import java.util.*;

// 中介者接口
interface Mediator {
    void sendMessage(String message, Colleague colleague);
}

// 同事抽象类
abstract class Colleague {
    protected Mediator mediator;
    public Colleague(Mediator mediator) { this.mediator = mediator; }
    public abstract void receive(String message);
}

// 具体中介者
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }

    public void sendMessage(String message, Colleague sender) {
        for(Colleague c : colleagues) {
            if(c != sender) { // 不给自己发
                c.receive(message);
            }
        }
    }
}

// 具体同事1
class User extends Colleague {
    private String name;
    public User(Mediator mediator, String name) { super(mediator); this.name = name; }
    public void send(String message) {
        System.out.println(name + " 发送消息: " + message);
        mediator.sendMessage(message, this);
    }
    public void receive(String message) {
        System.out.println(name + " 收到消息: " + message);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        ConcreteMediator chatRoom = new ConcreteMediator();

        User u1 = new User(chatRoom, "Alice");
        User u2 = new User(chatRoom, "Bob");
        User u3 = new User(chatRoom, "Charlie");

        chatRoom.addColleague(u1);
        chatRoom.addColleague(u2);
        chatRoom.addColleague(u3);

        u1.send("Hello, everyone!");
        u2.send("Hi, Alice!");
    }
}

备忘录

备忘录模式 = 保存对象状态 → 方便撤销/恢复 → 不破坏封装

Originator(发起人) = 拥有内部状态,并能创建/恢复备忘录

Memento(备忘录) = 存储发起人的内部状态

Caretaker(管理者) = 管理备忘录,不修改内容,只保存和提供恢复

java 复制代码
import java.util.*;

// 发起人
class Editor {
    private String content;

    public void setContent(String content) { this.content = content; }
    public String getContent() { return content; }

    // 创建备忘录
    public Memento save() {
        return new Memento(content);
    }

    // 恢复备忘录
    public void restore(Memento memento) {
        this.content = memento.getContent();
    }
}

// 备忘录
class Memento {
    private final String content;
    public Memento(String content) { this.content = content; }
    public String getContent() { return content; }
}

// 管理者
class Caretaker {
    private Stack<Memento> history = new Stack<>();
    public void save(Memento memento) { history.push(memento); }
    public Memento undo() { return history.pop(); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Editor editor = new Editor();
        Caretaker caretaker = new Caretaker();

        editor.setContent("Hello");
        caretaker.save(editor.save());

        editor.setContent("Hello, World");
        caretaker.save(editor.save());

        editor.setContent("Hello, World!!!");

        System.out.println("当前内容:" + editor.getContent());

        editor.restore(caretaker.undo());
        System.out.println("撤销一次:" + editor.getContent());

        editor.restore(caretaker.undo());
        System.out.println("撤销两次:" + editor.getContent());
    }
}

观察者

定义对象间的一种一对多依赖关系,让一个对象状态变化时,所有依赖它的对象都会收到通知并自动更新

Subject(主题/被观察者) = 保存观察者列表,状态变化时通知它们

Observer(观察者) = 定义接收更新的方法

ConcreteObserver(具体观察者) = 实现更新逻辑

java 复制代码
import java.util.*;

// 观察者接口
interface Observer {
    void update(String message);
}

// 主题接口
interface Subject {
    void attach(Observer o);    // 添加观察者
    void detach(Observer o);    // 移除观察者
    void notifyObservers();     // 通知所有观察者
}

// 具体主题
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String weather;

    public void setWeather(String weather) {
        this.weather = weather;
        notifyObservers(); // 天气变化,通知观察者
    }

    public void attach(Observer o) { observers.add(o); }
    public void detach(Observer o) { observers.remove(o); }
    public void notifyObservers() {
        for(Observer o : observers) {
            o.update(weather);
        }
    }
}

// 具体观察者1
class PhoneDisplay implements Observer {
    private String name;
    public PhoneDisplay(String name) { this.name = name; }
    public void update(String message) {
        System.out.println(name + " 手机显示天气: " + message);
    }
}

// 具体观察者2
class WindowDisplay implements Observer {
    private String name;
    public WindowDisplay(String name) { this.name = name; }
    public void update(String message) {
        System.out.println(name + " 窗口显示天气: " + message);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        WeatherStation station = new WeatherStation();

        Observer phone = new PhoneDisplay("Alice");
        Observer window = new WindowDisplay("Bob");

        station.attach(phone);
        station.attach(window);

        station.setWeather("晴天");
        station.setWeather("下雨");
    }
}

状态

  • State(状态接口) = 定义不同状态下的行为
  • ConcreteState(具体状态) = 实现状态对应行为
  • Context(环境类) = 持有当前状态,根据状态调用对应行为

允许对象在内部状态改变时改变它的行为

播放器根据当前状态自动选择行为,不用在按钮里写一堆 if/else 判断

java 复制代码
interface State {
    void pressPlay(MusicPlayer player);
    void pressPause(MusicPlayer player);
    void pressStop(MusicPlayer player);
}

// 播放状态
class PlayingState implements State {
    public void pressPlay(MusicPlayer player) {
        System.out.println("已经在播放中");
    }
    public void pressPause(MusicPlayer player) {
        System.out.println("暂停播放");
        player.setState(new PausedState());
    }
    public void pressStop(MusicPlayer player) {
        System.out.println("停止播放");
        player.setState(new StoppedState());
    }
}

// 暂停状态
class PausedState implements State {
    public void pressPlay(MusicPlayer player) {
        System.out.println("恢复播放");
        player.setState(new PlayingState());
    }
    public void pressPause(MusicPlayer player) {
        System.out.println("已经暂停");
    }
    public void pressStop(MusicPlayer player) {
        System.out.println("停止播放");
        player.setState(new StoppedState());
    }
}

// 停止状态
class StoppedState implements State {
    public void pressPlay(MusicPlayer player) {
        System.out.println("开始播放");
        player.setState(new PlayingState());
    }
    public void pressPause(MusicPlayer player) {
        System.out.println("停止状态不能暂停");
    }
    public void pressStop(MusicPlayer player) {
        System.out.println("已经停止");
    }
}

// 环境类
class MusicPlayer {
    private State state;

    public MusicPlayer() {
        state = new StoppedState(); // 初始状态
    }

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

    public void pressPlay() { state.pressPlay(this); }
    public void pressPause() { state.pressPause(this); }
    public void pressStop() { state.pressStop(this); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        MusicPlayer player = new MusicPlayer();

        player.pressPlay();   // 开始播放
        player.pressPause();  // 暂停播放
        player.pressPlay();   // 恢复播放
        player.pressStop();   // 停止播放
        player.pressPause();  // 停止状态不能暂停
    }
}

策略

Strategy(策略接口) = 定义算法/行为接口

ConcreteStrategy(具体策略) = 实现不同算法/行为

Context(环境类) = 持有策略对象,通过它调用对应行为

策略模式 = 把变化的算法封装起来 → 客户端可动态选择

java 复制代码
interface PaymentStrategy {
    void pay(double amount);
}

// 具体策略1:支付宝
class Alipay implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + " 元");
    }
}

// 具体策略2:微信
class WechatPay implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount + " 元");
    }
}

// 具体策略3:银行卡
class BankCardPay 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 setStrategy(PaymentStrategy strategy) { this.strategy = strategy; }
    public void pay(double amount) { strategy.pay(amount); }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext(new Alipay());
        context.pay(100);  // 支付宝支付 100 元

        context.setStrategy(new WechatPay());
        context.pay(200);  // 微信支付 200 元

        context.setStrategy(new BankCardPay());
        context.pay(300);  // 银行卡支付 300 元
    }
}

模板方法

模板方法模式 = 固定算法骨架,允许子类定制具体步骤

java 复制代码
abstract class Beverage {
    // 模板方法(固定流程)
    public final void prepare() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    private void boilWater() {
        System.out.println("烧水");
    }

    protected abstract void brew();        // 冲泡
    private void pourInCup() {
        System.out.println("倒入杯中");
    }

    protected abstract void addCondiments(); // 加调料
}

// 具体子类:咖啡
class Coffee extends Beverage {
    protected void brew() {
        System.out.println("用热水冲泡咖啡");
    }

    protected void addCondiments() {
        System.out.println("加糖和牛奶");
    }
}

// 具体子类:茶
class Tea extends Beverage {
    protected void brew() {
        System.out.println("用热水浸泡茶叶");
    }

    protected void addCondiments() {
        System.out.println("加柠檬");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        coffee.prepare();
        System.out.println("----------");
        Beverage tea = new Tea();
        tea.prepare();
    }
}

访问者

将作用于对象结构上的操作封装到独立访问者类中,使得在不修改对象的前提下可以定义新的操作

核心思想:

  • Visitor(访问者接口) = 定义访问不同类型元素的方法
  • ConcreteVisitor(具体访问者) = 实现具体操作
  • Element(元素接口) = 接受访问者
  • ConcreteElement(具体元素) = 实现接受访问者方法
  • ObjectStructure(对象结构) = 管理一组元素,允许访问者访问
java 复制代码
import java.util.*;

// 元素接口
interface Employee {
    void accept(Visitor visitor);
}

// 具体元素1:程序员
class Programmer implements Employee {
    private String name;
    private int hours;
    public Programmer(String name, int hours) { this.name = name; this.hours = hours; }
    public String getName() { return name; }
    public int getHours() { return hours; }
    public void accept(Visitor visitor) { visitor.visit(this); }
}

// 具体元素2:经理
class Manager implements Employee {
    private String name;
    private int teamSize;
    public Manager(String name, int teamSize) { this.name = name; this.teamSize = teamSize; }
    public String getName() { return name; }
    public int getTeamSize() { return teamSize; }
    public void accept(Visitor visitor) { visitor.visit(this); }
}

// 访问者接口
interface Visitor {
    void visit(Programmer programmer);
    void visit(Manager manager);
}

// 具体访问者:计算工资
class SalaryVisitor implements Visitor {
    public void visit(Programmer programmer) {
        System.out.println(programmer.getName() + " 工资:" + programmer.getHours() * 100 + " 元");
    }
    public void visit(Manager manager) {
        System.out.println(manager.getName() + " 工资:" + (manager.getTeamSize() * 500 + 3000) + " 元");
    }
}

// 对象结构
class Company {
    private List<Employee> employees = new ArrayList<>();
    public void addEmployee(Employee e) { employees.add(e); }
    public void accept(Visitor visitor) {
        for(Employee e : employees) e.accept(visitor);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Company company = new Company();
        company.addEmployee(new Programmer("Alice", 160));
        company.addEmployee(new Manager("Bob", 5));

        SalaryVisitor salaryVisitor = new SalaryVisitor();
        company.accept(salaryVisitor);
    }
}
相关推荐
砍光二叉树3 小时前
【设计模式】行为型-迭代器模式
设计模式·迭代器模式
Elaine3364 小时前
【Agent 设计模式全景图:从 ReAct 到工业级多智能体架构】
设计模式·llm·软件架构·ai agent
han_5 小时前
JavaScript设计模式(六):职责链模式实现与应用
前端·javascript·设计模式
无籽西瓜a6 小时前
【西瓜带你学设计模式 | 第三期-工厂方法模式】工厂方法模式——定义、实现方式、优缺点与适用场景以及注意事项
java·后端·设计模式·工厂方法模式
无籽西瓜a6 小时前
【西瓜带你学设计模式 | 第四期 - 抽象工厂模式】抽象工厂模式 —— 定义、核心结构、实战示例、优缺点与适用场景及模式区别
java·后端·设计模式·软件工程·抽象工厂模式
￰meteor8 小时前
23种设计模式 -【抽象工厂】
后端·设计模式
程序员小寒8 小时前
JavaScript设计模式(五):装饰者模式实现与应用
前端·javascript·设计模式
workflower1 天前
设计模式的分类
设计模式·集成测试·软件工程·软件构建·软件需求·结对编程
han_1 天前
JavaScript设计模式(五):装饰者模式实现与应用
前端·javascript·设计模式