当前位置: 首页 > news >正文

腾讯元宝 Java 中的 23 种设计模式(GoF 设计模式)

稚辉君
分享于2025-09-160
java 23 设计模式
好的,Java 中的 23 种设计模式(GoF 设计模式)是面向对象软件设计的精华。它们分为三大类:​​创建型​​、​​结构型​​和​​行为型​​。

下面我将为你详细解析这 23 种模式,并提供 Java 代码示例。

一、创建型模式 (5种)
​​核心思想:​​ 关注对象的创建过程,将对象的创建与使用分离,使系统更灵活。

​​单例模式 (Singleton)​​

​​目的:​​ 保证一个类只有一个实例,并提供全局访问点。

​​实现:​​ 私有化构造方法,提供一个静态方法返回唯一实例。

​​示例:​​ 配置文件管理、线程池、日志对象。

public class Singleton {
// 饿汉式(线程安全)
private static final Singleton INSTANCE = new Singleton();

private Singleton() {} // 私有构造器public static Singleton getInstance() {return INSTANCE;
}

}

// 或者使用静态内部类(懒加载,线程安全)
public class SingletonLazy {
private SingletonLazy() {}

private static class Holder {private static final SingletonLazy INSTANCE = new SingletonLazy();
}public static SingletonLazy getInstance() {return Holder.INSTANCE;
}

}
​​工厂方法模式 (Factory Method)​​

​​目的:​​ 定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

​​示例:​​ java.util.Calendar#getInstance()。

public interface Product {
void use();
}

public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println(“Using Product A”);
}
}

public abstract class Creator {
public abstract Product createProduct(); // 工厂方法

public void someOperation() {Product product = createProduct();product.use();
}

}

public class ConcreteCreatorA extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductA(); // 创建具体产品A
}
}
​​抽象工厂模式 (Abstract Factory)​​

​​目的:​​ 提供一个接口,用于创建​​相关或依赖对象​​的​​家族​​,而不需要明确指定具体类。

​​示例:​​ GUI 库(创建一套跨平台的按钮、文本框等)。

// 产品族A:现代风格
public class ModernChair implements Chair { /* … / }
public class ModernSofa implements Sofa { /
… */ }

// 产品族B:古典风格
public class ClassicChair implements Chair { /* … / }
public class ClassicSofa implements Sofa { /
… */ }

// 抽象工厂
public interface FurnitureFactory {
Chair createChair();
Sofa createSofa();
}

// 具体工厂A
public class ModernFactory implements FurnitureFactory {
@Override
public Chair createChair() { return new ModernChair(); }
@Override
public Sofa createSofa() { return new ModernSofa(); }
}
// 具体工厂B
public class ClassicFactory implements FurnitureFactory {
@Override
public Chair createChair() { return new ClassicChair(); }
@Override
public Sofa createSofa() { return new ClassicSofa(); }
}
​​建造者模式 (Builder)​​

​​目的:​​ 将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。适用于构造参数多、有可选参数的复杂对象。

​​示例:​​ StringBuilder, Lombok的 @Builder。

public class Computer {
private final String CPU;
private final String RAM;
private final String SSD; // 可选
private final String HDD; // 可选

// 私有构造器,通过Builder构建
private Computer(Builder builder) {this.CPU = builder.CPU;this.RAM = builder.RAM;this.SSD = builder.SSD;this.HDD = builder.HDD;
}public static class Builder {private final String CPU; // 必需private final String RAM; // 必需private String SSD;private String HDD;public Builder(String cpu, String ram) {this.CPU = cpu;this.RAM = ram;}public Builder setSSD(String ssd) {this.SSD = ssd;return this;}public Builder setHDD(String hdd) {this.HDD = hdd;return this;}public Computer build() {return new Computer(this);}
}

}

// 使用
Computer myPC = new Computer.Builder(“Intel i7”, “16GB”)
.setSSD(“512GB”)
.build();
​​原型模式 (Prototype)​​

​​目的:​​ 用原型实例指定创建对象的种类,并通过​​复制​​这些原型创建新的对象。

​​实现:​​ 实现 Cloneable接口,重写 clone()方法。

​​示例:​​ 创建成本高昂的对象(如数据库查询结果),或需要避免重复初始化流程的对象。

public class Sheep implements Cloneable {
private String name;
public Sheep(String name) { this.name = name; }

@Override
protected Object clone() throws CloneNotSupportedException {return super.clone(); // 浅拷贝
}

}
二、结构型模式 (7种)
​​核心思想:​​ 关注类和对象的组合,形成更大的结构。

​​适配器模式 (Adapter)​​

​​目的:​​ 将一个类的接口转换成客户希望的另外一个接口。使原本接口不兼容的类可以一起工作。

​​分类:​​ 类适配器(继承)、对象适配器(组合)。

​​示例:​​ java.util.Arrays#asList()。

// 目标接口(客户期望的接口)
public interface Target {
void request();
}

// 需要被适配的类
public class Adaptee {
public void specificRequest() {
System.out.println(“Adaptee’s specific request”);
}
}

// 对象适配器(推荐,使用组合)
public class Adapter implements Target {
private Adaptee adaptee;

public Adapter(Adaptee adaptee) {this.adaptee = adaptee;
}@Override
public void request() {adaptee.specificRequest(); // 调用被适配者的方法
}

}
​​桥接模式 (Bridge)​​

​​目的:​​ 将抽象部分与其实现部分分离,使它们都可以独立地变化。用组合代替继承。

​​示例:​​ JDBC 驱动。

// 实现化接口
public interface Color {
void applyColor();
}
public class Red implements Color {
@Override
public void applyColor() { System.out.print(“红色的”); }
}

// 抽象化角色
public abstract class Shape {
protected Color color; // 桥接的关键:持有实现化角色的引用
public Shape(Color color) { this.color = color; }
public abstract void draw();
}

public class Circle extends Shape {
public Circle(Color color) { super(color); }
@Override
public void draw() {
color.applyColor();
System.out.println(“圆形”);
}
}
​​组合模式 (Composite)​​

​​目的:​​ 将对象组合成​​树形结构​​以表示“部分-整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。

​​示例:​​ 文件系统、GUI 容器组件。

// 组件接口
public interface FileSystemComponent {
void showInfo();
}

// 叶子节点
public class File implements FileSystemComponent {
private String name;
public File(String name) { this.name = name; }
@Override
public void showInfo() { System.out.println("File: " + name); }
}

// 容器节点
public class Directory implements FileSystemComponent {
private String name;
private List children = new ArrayList<>();

public Directory(String name) { this.name = name; }public void add(FileSystemComponent comp) { children.add(comp); }@Override
public void showInfo() {System.out.println("Directory: " + name);for (FileSystemComponent comp : children) {comp.showInfo(); // 递归调用}
}

}
​​装饰器模式 (Decorator)​​

​​目的:​​ 动态地给一个对象添加一些额外的职责。就增加功能来说,比生成子类更为灵活。

​​示例:​​ java.io包中的 InputStream, OutputStream, Reader, Writer。

// 组件接口
public interface Coffee {
double getCost();
String getDescription();
}

// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public double getCost() { return 2.0; }
@Override
public String getDescription() { return “Simple Coffee”; }
}

// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; }
}

// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) { super(coffee); }
@Override
public double getCost() { return decoratedCoffee.getCost() + 0.5; }
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + “, Milk”;
}
}
​​外观模式 (Facade)​​

​​目的:​​ 为子系统中的一组接口提供一个一致的界面,定义一个高层接口,使得这一子系统更加容易使用。

​​示例:​​ 控制器(Controller)封装多个Service的调用。

// 复杂的子系统
public class CPU { public void start() { /* … / } }
public class Memory { public void load() { /
/ } }
public class HardDrive { public void read() { /
… */ } }

// 外观类
public class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;

public ComputerFacade() {this.cpu = new CPU();this.memory = new Memory();this.hardDrive = new HardDrive();
}// 提供一个简单的启动方法,隐藏子系统的复杂性
public void startComputer() {cpu.start();memory.load();hardDrive.read();System.out.println("Computer started!");
}

}
​​享元模式 (Flyweight)​​

​​目的:​​ 运用共享技术有效地支持大量细粒度的对象。避免创建大量相似对象的开销。

​​核心:​​ 区分内部状态(共享)和外部状态(不可共享)。

​​示例:​​ Java String 常量池、线程池、数据库连接池。

public interface Shape {
void draw(Color color); // color是外部状态,由客户端传入
}

public class Circle implements Shape {
private String type = “Circle”; // 内部状态,可以共享
@Override
public void draw(Color color) {
System.out.println(“Drawing a ” + color + “ ” + type);
}
}

// 享元工厂
public class ShapeFactory {
private static final Map<String, Shape> circleMap = new HashMap<>();

public static Shape getCircle(String type) {Shape circle = circleMap.get(type);if (circle == null) {circle = new Circle(); // 只有第一次会创建新对象circleMap.put(type, circle);}return circle;
}

}
​​代理模式 (Proxy)​​

​​目的:​​ 为其他对象提供一种代理以控制对这个对象的访问。

​​分类:​​ 远程代理、虚拟代理(延迟加载)、保护代理、缓存代理等。

​​示例:​​ Spring AOP。

public interface Image {
void display();
}

// 真实对象
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk(); // 昂贵的初始化
}
private void loadFromDisk() { System.out.println("Loading " + filename); }
@Override
public void display() { System.out.println("Displaying " + filename); }
}

// 代理对象(控制访问,实现延迟加载)
public class ProxyImage implements Image {
private String filename;
private RealImage realImage; // 对真实对象的引用

public ProxyImage(String filename) { this.filename = filename; }@Override
public void display() {if (realImage == null) {realImage = new RealImage(filename); // 只在需要时创建真实对象}realImage.display();
}

}
三、行为型模式 (11种)
​​核心思想:​​ 关注对象之间的通信和职责分配。

​​责任链模式 (Chain of Responsibility)​​

​​目的:​​ 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

​​示例:​​ Java Servlet 中的 Filter、异常处理机制。

public abstract class Logger {
public static int INFO = 1, DEBUG = 2, ERROR = 3;
protected int level;
protected Logger nextLogger; // 链中的下一个元素

public void setNextLogger(Logger nextLogger) {this.nextLogger = nextLogger;
}public void logMessage(int level, String message) {if (this.level <= level) { // 判断是否能处理该级别的日志write(message);}if (nextLogger != null) { // 传递给责任链的下一个节点nextLogger.logMessage(level, message);}
}
abstract protected void write(String message);

}
​​命令模式 (Command)​​

​​目的:​​ 将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化,支持请求的排队、记录、撤销等操作。

​​示例:​​ 线程池、任务队列、GUI 按钮操作。

// 命令接口
public interface Command {
void execute();
}

// 接收者(真正执行命令的对象)
public class Light {
public void turnOn() { System.out.println(“Light is on”); }
public void turnOff() { System.out.println(“Light is off”); }
}

// 具体命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
@Override
public void execute() { light.turnOn(); }
}

// 调用者/请求者
public class RemoteControl {
private Command command;
public void setCommand(Command command) { this.command = command; }
public void pressButton() { command.execute(); }
}
​​解释器模式 (Interpreter)​​

​​目的:​​ 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

​​应用场景:​​ 特定领域简单语言、正则表达式、SQL 解析。​​使用较少​​。

​​迭代器模式 (Iterator)​​

​​目的:​​ 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

​​示例:​​ Java 集合框架中的 Iterator。

// 自定义集合
public class MyCollection implements Iterable {
private String[] items = {“A”, “B”, “C”};

@Override
public Iterator<String> iterator() {return new MyIterator();
}// 具体迭代器
private class MyIterator implements Iterator<String> {private int index = 0;@Overridepublic boolean hasNext() { return index < items.length; }@Overridepublic String next() { return items[index++]; }
}

}
​​中介者模式 (Mediator)​​

​​目的:​​ 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

​​示例:​​ MVC 框架中的 Controller、聊天室。

​​备忘录模式 (Memento)​​

​​目的:​​ 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

​​三要素:​​ Originator(原发器)、Memento(备忘录)、Caretaker(负责人)。

// 原发器
public class Editor {
private String content;
public void setContent(String content) { this.content = content; }
public String getContent() { return content; }

// 创建备忘录
public EditorMemento save() { return new EditorMemento(content); }
// 恢复备忘录
public void restore(EditorMemento memento) { this.content = memento.getSavedContent(); }

}

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

// 负责人(存储备忘录历史)
public class History {
private Stack stack = new Stack<>();
public void push(EditorMemento memento) { stack.push(memento); }
public EditorMemento pop() { return stack.pop(); }
}
​​观察者模式 (Observer)​​

​​目的:​​ 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

​​示例:​​ Java PropertyChangeListener, EventListener, React/Vue 的数据响应式原理。

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

// 被观察者(主题)
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}

public class ConcreteSubject implements Subject {
private List observers = new ArrayList<>();
private String state;

public void setState(String state) {this.state = state;notifyObservers(); // 状态改变,通知所有观察者
}@Override
public void registerObserver(Observer o) { observers.add(o); }
@Override
public void removeObserver(Observer o) { observers.remove(o); }
@Override
public void notifyObservers() {for (Observer o : observers) {o.update(state);}
}

}
​​状态模式 (State)​​

​​目的:​​ 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

​​示例:​​ 订单状态(待支付、已支付、已发货)、游戏角色状态(站立、跑步、跳跃)。

// 状态接口
public interface State {
void handle(Context context);
}

public class ConcreteStateA implements State {
@Override
public void handle(Context context) {
System.out.println(“Handling in State A. Changing state to B.”);
context.setState(new ConcreteStateB()); // 改变上下文的状态
}
}

public class ConcreteStateB implements State {
@Override
public void handle(Context context) {
System.out.println(“Handling in State B. Changing state to A.”);
context.setState(new ConcreteStateA());
}
}

// 上下文类(拥有状态)
public class Context {
private State state;
public Context(State state) { this.state = state; }
public void setState(State state) { this.state = state; }
public void request() { state.handle(this); } // 请求委托给当前状态处理
}
​​策略模式 (Strategy)​​

​​目的:​​ 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

​​示例:​​ java.util.Comparator, 支付方式(支付宝、微信、银行卡)。

// 策略接口
public interface PaymentStrategy {
void pay(int amount);
}

public class CreditCardStrategy implements PaymentStrategy {
private String cardNumber;
public CreditCardStrategy(String cardNumber) { this.cardNumber = cardNumber; }
@Override
public void pay(int amount) {
System.out.println(“Paid “ + amount + “ using Credit Card: ” + cardNumber);
}
}

public class PaypalStrategy implements PaymentStrategy {
private String email;
public PaypalStrategy(String email) { this.email = email; }
@Override
public void pay(int amount) {
System.out.println(“Paid “ + amount + “ using PayPal: ” + email);
}
}

// 上下文
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
​​模板方法模式 (Template Method)​​

​​目的:​​ 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

​​示例:​​ javax.servlet.http.HttpServlet的 doGet(), doPost()。

public abstract class Game {
// 模板方法(final 防止子类重写算法骨架)
public final void play() {
initialize();
startPlay();
endPlay();
}

// 抽象方法,由子类实现
abstract void initialize();
abstract void startPlay();
abstract void endPlay();

}

public class Cricket extends Game {
@Override
void initialize() { System.out.println(“Cricket Game Initialized!”); }
@Override
void startPlay() { System.out.println(“Cricket Game Started!”); }
@Override
void endPlay() { System.out.println(“Cricket Game Finished!”); }
}
​​访问者模式 (Visitor)​​

​​目的:​​ 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

​​核心:​​ 双分派(Double Dispatch)。​​数据结构稳定,操作经常变化时使用​​。

// 元素接口
public interface ComputerPart {
void accept(ComputerPartVisitor visitor);
}

// 具体元素
public class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this); // 调用访问者针对Keyboard的方法
}
}

// 访问者接口
public interface ComputerPartVisitor {
void visit(Keyboard keyboard);
void visit(Mouse mouse);
}

// 具体访问者
public class DisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Keyboard keyboard) {
System.out.println(“Displaying Keyboard.”);
}
@Override
public void visit(Mouse mouse) {
System.out.println(“Displaying Mouse.”);
}
}
总结与记忆口诀
​​创建型:​​ 单例、工厂、抽象工厂、建造者、原型。(​​怎么创建​​)

​​结构型:​​ 适配器、桥接、组合、装饰器、外观、享元、代理。(​​怎么组装​​)

​​行为型:​​ 责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者。(​​怎么互动​​)

​​学习建议:​​

​​理解意图:​​ 每个模式都是为了解决特定的问题而生的。

​​查看源码:​​ JDK 和主流框架(Spring, MyBatis)中大量使用了这些模式。

​​切勿滥用:​​ 模式是手段,不是目的。简单的需求用简单的代码,不要为了用模式而用模式。


文章转载自:

http://vvR9f7Tu.jcyrs.cn
http://nBKtyiKU.jcyrs.cn
http://k0mWHWdo.jcyrs.cn
http://l9b8i4q7.jcyrs.cn
http://18Ky9qRh.jcyrs.cn
http://8ALdRSRg.jcyrs.cn
http://QkrTr4hC.jcyrs.cn
http://A5ZxNtI9.jcyrs.cn
http://rVjwJO7d.jcyrs.cn
http://IxF3Etzh.jcyrs.cn
http://aJOt0KDw.jcyrs.cn
http://hu8WGzL8.jcyrs.cn
http://1AlICZJ8.jcyrs.cn
http://ApcYbfgk.jcyrs.cn
http://mCmEfiJI.jcyrs.cn
http://kAaqe4NW.jcyrs.cn
http://35g9sXzc.jcyrs.cn
http://TDNyLsfr.jcyrs.cn
http://1d47h6bM.jcyrs.cn
http://SPcHIU7K.jcyrs.cn
http://WjkZxtXW.jcyrs.cn
http://xxMI50Gg.jcyrs.cn
http://3CyhMD8i.jcyrs.cn
http://OHoAG6Mg.jcyrs.cn
http://mwUfgD0t.jcyrs.cn
http://HdeoUXu6.jcyrs.cn
http://e2d4ZHhK.jcyrs.cn
http://OF6sL5SP.jcyrs.cn
http://QDVcg4Y9.jcyrs.cn
http://Gl4F7oBi.jcyrs.cn
http://www.dtcms.com/a/385944.html

相关文章:

  • Excel:根据数据信息自动生成模板数据(多个Sheet)
  • hibernate和mybatis的差异,以及这种类似场景的优缺点和选择
  • 设计模式之:观察者模式
  • 【pycharm】ubuntu24.04 安装配置index-tts及webdemo快速上手
  • Java 设计模式——观察者模式:从 4 种写法到 SpringBoot 进阶
  • “光敏” 黑科技:杜绝手机二维码读取时的 NFC 误触
  • AIGC(生成式AI)试用 36 -- shell脚本(辅助生成)
  • 【计算机网络 | 第17篇】DNS资源记录和报文
  • Flowise安全外网访问指南:基于cpolar的隧道配置详解
  • MySQL OCP认证[特殊字符]Oracle OCP认证
  • Springboot使用Freemark模板生成XML数据
  • 【数据工程】 10. 半结构化数据与 NoSQL 数据库
  • HarmonyOS应用开发:深入ArkUI声明式开发与性能优化实践
  • Vue: 组件注册
  • 408考研计算机网络第38题真题解析(2024)
  • Uni-app 生命周期全解析
  • JavaEE开发技术(第一章:Servlet基础)
  • 【数据结构】跳表
  • 设计模式-桥接模式02
  • Linux 基础命令详解与学习笔记
  • 设计模式(C++)详解——桥接模式(2)
  • 鹧鸪云光储流程系统:以智能仓储管理,驱动项目高效协同
  • DIY Linux 桌面:WiFi 管理器
  • 从 Pump.fun「直播」看热点币的生与死
  • 《算法闯关指南:优选算法-双指针》--05有效三角形的个数,06查找总价值为目标值的两个商品
  • Java List 详解:从基础到进阶的全面指南
  • 【问题】自启动的容器在开机重启后 都退出了,未能正常启动
  • 苹果手机上有没有可以定时提醒做事的工具
  • blender多个动作导入到unity
  • 通过adb dump activity的configChanges配置