java-design-patterns by diego-tobalina/vibe-coding
npx skills add https://github.com/diego-tobalina/vibe-coding --skill java-design-patternsJava 中所有四人组设计模式的快速参考。
| 模式 | 使用场景 | 避免使用场景 |
|---|---|---|
| 单例模式 | 需要且仅需要一个实例(数据库连接、缓存) | 需要多个实例,测试困难 |
| 工厂方法模式 | 将实例化委托给子类 | 单一产品类型,创建过程简单 |
| 抽象工厂模式 | 创建一系列相关的对象 | 单一产品,产品类型经常变化 |
| 建造者模式 | 多个可选参数,需要分步构建 | 参数少,对象简单 |
| 原型模式 | 创建对象成本高,克隆现有对象 | 对象简单,深克隆复杂 |
| 模式 | 使用场景 |
|---|
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 避免使用场景 |
|---|
| 适配器模式 | 接口与客户端不兼容 | 接口已经兼容 |
| 桥接模式 | 抽象和实现需要独立变化 | 简单的层次结构,变化少 |
| 组合模式 | 树形结构,统一处理个体和组合 | 无层次结构,只有叶子节点 |
| 装饰器模式 | 动态添加职责 | 过多装饰器导致混乱 |
| 外观模式 | 简化复杂子系统的接口 | 子系统简单,需要直接访问 |
| 享元模式 | 大量相似对象,共享状态以节省内存 | 对象少,状态各异 |
| 代理模式 | 控制访问、延迟加载、日志记录 | 简单的对象访问,增加不必要的复杂性 |
| 模式 | 使用场景 | 避免使用场景 |
|---|---|---|
| 责任链模式 | 多个处理器,动态链 | 链是固定的,处理简单 |
| 命令模式 | 队列/撤销操作,解耦发送者和接收者 | 简单的直接调用,无需撤销 |
| 迭代器模式 | 遍历集合而不暴露内部结构 | 简单的集合,Java 的 Iterator 已足够 |
| 中介者模式 | 多个对象间复杂的通信 | 对象少,交互简单 |
| 备忘录模式 | 保存/恢复对象状态(撤销) | 状态简单,或不需要持久化 |
| 观察者模式 | 一对多依赖关系,事件订阅 | 不需要通知,紧耦合可以接受 |
| 状态模式 | 对象行为随状态改变 | 状态少,简单条件即可满足 |
| 策略模式 | 多种可互换的算法 | 单一算法,无变化 |
| 模板方法模式 | 具有可变步骤的通用算法 | 算法完全不同 |
| 访问者模式 | 将操作与对象结构分离 | 结构经常变化,操作少 |
确保一个类只有一个实例,并提供全局访问点。
// 线程安全的双重检查锁定单例
public final class DatabaseConnection {
private static volatile DatabaseConnection instance;
private DatabaseConnection() {
// 私有构造函数
}
public static DatabaseConnection getInstance() {
if (instance == null) {
synchronized (DatabaseConnection.class) {
if (instance == null) {
instance = new DatabaseConnection();
}
}
}
return instance;
}
}
// 替代方案:枚举单例(序列化安全,反射安全)
public enum EnumSingleton {
INSTANCE;
public void doSomething() {
// 业务逻辑
}
}
适用于: 数据库连接、缓存、线程池、配置
创建对象而不指定具体类。
// 产品接口
public interface Notification {
void send(String message);
}
// 具体产品
public class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
public class SmsNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
// 创建者
public abstract class NotificationFactory {
abstract Notification createNotification();
public void notifyUser(String message) {
Notification notification = createNotification();
notification.send(message);
}
}
// 具体创建者
public class EmailNotificationFactory extends NotificationFactory {
Notification createNotification() {
return new EmailNotification();
}
}
// 用法
NotificationFactory factory = new EmailNotificationFactory();
factory.notifyUser("Hello!");
创建一系列相关的对象。
// 抽象工厂
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂
public class WindowsFactory implements GUIFactory {
public Button createButton() { return new WindowsButton(); }
public Checkbox createCheckbox() { return new WindowsCheckbox(); }
}
public class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Checkbox createCheckbox() { return new MacCheckbox(); }
}
// 用法
GUIFactory factory = System.getProperty("os.name").contains("Windows")
? new WindowsFactory() : new MacFactory();
Button button = factory.createButton();
分步构建复杂对象。
// 使用 Lombok(推荐)
@Data
@Builder
public class User {
private String id;
private String email;
private String name;
private int age;
private String address;
}
// 用法
User user = User.builder()
.id("123")
.email("user@example.com")
.name("John")
.build();
// 手动实现
public class UserBuilder {
private User user = new User();
public UserBuilder withEmail(String email) {
user.setEmail(email);
return this;
}
public UserBuilder withName(String name) {
user.setName(name);
return this;
}
public User build() {
// 验证
if (user.getEmail() == null) {
throw new IllegalStateException("Email is required");
}
return user;
}
}
克隆现有对象。
public interface Prototype<T> extends Cloneable {
T clone();
}
public class Document implements Prototype<Document> {
private String title;
private String content;
private List<String> tags;
// 深拷贝
@Override
public Document clone() {
try {
Document cloned = (Document) super.clone();
cloned.tags = new ArrayList<>(this.tags); // 深拷贝列表
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
// 用法
Document template = new Document("Template", "Content", Arrays.asList("tag1"));
Document copy = template.clone();
将一个接口转换成客户端期望的另一个接口。
// 目标接口
public interface MediaPlayer {
void play(String filename);
}
// 适配者(现有接口)
public interface AdvancedMediaPlayer {
void playMp4(String filename);
void playVlc(String filename);
}
// 适配器
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("mp4")) {
advancedPlayer = new Mp4Player();
}
}
public void play(String filename) {
advancedPlayer.playMp4(filename);
}
}
将抽象与实现分离。
// 实现接口
public interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
// 具体实现
public class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double r) {
System.out.printf("API1.circle at (%.2f,%.2f) radius %.2f%n", x, y, r);
}
}
// 抽象
public abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI api) {
this.drawingAPI = api;
}
public abstract void draw();
}
// 精化抽象
public class CircleShape extends Shape {
private double x, y, radius;
public CircleShape(double x, double y, double r, DrawingAPI api) {
super(api);
this.x = x; this.y = y; this.radius = r;
}
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
// 用法
Shape circle = new CircleShape(1, 2, 3, new DrawingAPI1());
circle.draw();
将对象组合成树形结构。
// 组件
public interface Employee {
void showEmployeeDetails();
double getSalary();
}
// 叶子
public class Developer implements Employee {
private String name;
private double salary;
public void showEmployeeDetails() {
System.out.println(name + " - " + salary);
}
public double getSalary() { return salary; }
}
// 组合
public class Manager implements Employee {
private String name;
private double salary;
private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee emp) {
employees.add(emp);
}
public void showEmployeeDetails() {
System.out.println(name + " - " + salary);
for (Employee emp : employees) {
emp.showEmployeeDetails();
}
}
public double getSalary() {
return salary + employees.stream().mapToDouble(Employee::getSalary).sum();
}
}
动态添加职责。
// 组件
public interface Coffee {
double getCost();
String getDescription();
}
// 具体组件
public class SimpleCoffee implements Coffee {
public double getCost() { return 10; }
public String getDescription() { return "Simple coffee"; }
}
// 装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
public double getCost() {
return decoratedCoffee.getCost();
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// 具体装饰器
public class Milk extends CoffeeDecorator {
public Milk(Coffee coffee) { super(coffee); }
public double getCost() { return super.getCost() + 2; }
public String getDescription() { return super.getDescription() + ", milk"; }
}
// 用法
Coffee coffee = new SimpleCoffee();
coffee = new Milk(coffee);
coffee = new Sugar(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
为复杂子系统提供简化接口。
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 start() {
cpu.freeze();
memory.load(0, hardDrive.read(0, 1024));
cpu.jump(0);
cpu.execute();
}
public void shutdown() {
cpu.stop();
memory.clear();
}
}
// 用法 - 简单接口隐藏了复杂性
ComputerFacade computer = new ComputerFacade();
computer.start();
共享数据以支持大量对象。
// 享元
public interface Character {
void display(int position);
}
// 具体享元(内部状态)
public class CharacterGlyph implements Character {
private char symbol; // 共享
private String font; // 共享
public CharacterGlyph(char symbol, String font) {
this.symbol = symbol;
this.font = font;
}
public void display(int position) { // 外部状态
System.out.println(symbol + " at position " + position);
}
}
// 享元工厂
public class CharacterFactory {
private Map<String, Character> characters = new HashMap<>();
public Character getCharacter(char symbol, String font) {
String key = symbol + font;
return characters.computeIfAbsent(key,
k -> new CharacterGlyph(symbol, font));
}
}
占位符,用于控制访问。
// 主题
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);
}
public void display() {
System.out.println("Displaying " + filename);
}
}
// 代理
public 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("photo.jpg"); // 尚未加载
image.display(); // 加载并显示
将请求沿着处理链传递。
public abstract class Logger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected Logger nextLogger;
public void setNextLogger(Logger next) {
this.nextLogger = next;
}
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);
}
// 具体处理器
public class ConsoleLogger extends Logger {
public ConsoleLogger(int level) { this.level = level; }
protected void write(String message) {
System.out.println("Console: " + message);
}
}
// 用法 - 将它们链接在一起
Logger loggerChain = new ConsoleLogger(Logger.INFO);
Logger errorLogger = new ErrorLogger(Logger.ERROR);
loggerChain.setNextLogger(errorLogger);
loggerChain.logMessage(Logger.INFO, "Info message");
将请求封装为对象。
// 命令
public interface Command {
void execute();
void undo();
}
// 接收者
public class Light {
public void on() { System.out.println("Light is on"); }
public void off() { System.out.println("Light is off"); }
}
// 具体命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); }
public void undo() { light.off(); }
}
// 调用者
public class RemoteControl {
private Command command;
public void setCommand(Command cmd) { this.command = cmd; }
public void pressButton() { command.execute(); }
public void pressUndo() { command.undo(); }
}
// 用法
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();
遍历集合而不暴露内部结构。
// 迭代器
public interface Iterator<T> {
boolean hasNext();
T next();
}
// 聚合
public interface Container<T> {
Iterator<T> getIterator();
}
// 具体集合
public class NameRepository implements Container<String> {
private String[] names = {"Robert", "John", "Julie"};
public Iterator<String> getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator<String> {
private int index;
public boolean hasNext() {
return index < names.length;
}
public String next() {
return hasNext() ? names[index++] : null;
}
}
}
// 用法 - Java 的增强 for 循环内部使用了 Iterator
NameRepository repo = new NameRepository();
for (Iterator<String> it = repo.getIterator(); it.hasNext(); ) {
System.out.println(it.next());
}
封装对象间的交互方式。
// 中介者
public interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者
public class ChatMediatorImpl implements ChatMediator {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
public void sendMessage(String msg, User sender) {
for (User user : users) {
if (user != sender) {
user.receive(msg);
}
}
}
}
// 同事类
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name) {
this.mediator = med;
this.name = name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
// 具体同事类
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
public void send(String msg) {
System.out.println(name + ": Sending Message=" + msg);
mediator.sendMessage(msg, this);
}
public void receive(String msg) {
System.out.println(name + ": Received Message=" + msg);
}
}
// 用法
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "John");
User user2 = new UserImpl(mediator, "Jane");
mediator.addUser(user1);
mediator.addUser(user2);
user1.send("Hi Jane!");
捕获和恢复对象状态。
// 备忘录
public class EditorMemento {
private final String content;
private final LocalDateTime savedAt;
public EditorMemento(String content) {
this.content = content;
this.savedAt = LocalDateTime.now();
}
public String getContent() { return content; }
}
// 原发器
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) {
content = memento.getContent();
}
}
// 负责人
public class History {
private List<EditorMemento> mementos = new ArrayList<>();
private Editor editor;
public History(Editor editor) {
this.editor = editor;
}
public void backup() {
mementos.add(editor.save());
}
public void undo() {
if (!mementos.isEmpty()) {
EditorMemento memento = mementos.remove(mementos.size() - 1);
editor.restore(memento);
}
}
}
// 用法
Editor editor = new Editor();
History history = new History(editor);
editor.setContent("Version 1");
history.backup();
editor.setContent("Version 2");
history.undo(); // 恢复到 "Version 1"
定义一对多依赖关系。
// 观察者
public interface StockObserver {
void update(String stockSymbol, double price);
}
// 主题
public interface StockSubject {
void registerObserver(StockObserver observer);
void removeObserver(StockObserver observer);
void notifyObservers();
}
// 具体主题
public class StockPrice implements StockSubject {
private List<StockObserver> observers = new ArrayList<>();
private String symbol;
private double price;
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
public void registerObserver(StockObserver observer) {
observers.add(observer);
}
public void notifyObservers() {
for (StockObserver observer : observers) {
observer.update(symbol, price);
}
}
}
// 具体观察者
public class MobileApp implements StockObserver {
public void update(String symbol, double price) {
System.out.println("MobileApp: " + symbol + " is now $" + price);
}
}
// 使用 Java 内置功能的用法(java.util.Observer 已弃用,使用 PropertyChangeListener)
StockPrice stock = new StockPrice();
stock.registerObserver(new MobileApp());
stock.registerObserver(new WebApp());
stock.setPrice(150.00); // 通知所有观察者
状态改变时改变行为。
// 状态
public interface VendingMachineState {
void insertMoney();
void ejectMoney();
void dispense();
}
// 具体状态
public class NoMoneyState implements VendingMachineState {
private VendingMachine machine;
public NoMoneyState(VendingMachine machine) {
this.machine = machine;
}
public void insertMoney() {
System.out.println("Money inserted");
machine.setState(machine.getHasMoneyState());
}
public void ejectMoney() {
System.out.println("No money to eject");
}
public void dispense() {
System.out.println("Insert money first");
}
}
// 上下文
public class VendingMachine {
private VendingMachineState noMoneyState;
private VendingMachineState hasMoneyState;
private VendingMachineState currentState;
public VendingMachine() {
noMoneyState = new NoMoneyState(this);
hasMoneyState = new HasMoneyState(this);
currentState = noMoneyState;
}
public void setState(VendingMachineState state) {
this.currentState = state;
}
public void insertMoney() { currentState.insertMoney(); }
public void ejectMoney() { currentState.ejectMoney(); }
public void dispense() { currentState.dispense(); }
public VendingMachineState getNoMoneyState() { return noMoneyState; }
public VendingMachineState getHasMoneyState() { return hasMoneyState; }
}
一系列可互换的算法。
// 策略
public interface PaymentStrategy {
void pay(int amount);
}
// 具体策略
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card " + cardNumber);
}
}
public class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
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);
}
}
// 用法
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new CreditCardPayment("1234-5678"));
cart.checkout(100);
cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
cart.checkout(50);
在基类中定义算法骨架。
// 包含模板方法的抽象类
public abstract class DataImporter {
// 模板方法 - 定义算法
public final void importData(String filePath) {
String data = readFile(filePath);
validate(data);
parse(data);
save(data);
notifyCompletion();
}
// 具体方法
protected String readFile(String filePath) {
// 通用实现
return "file content";
}
protected void notifyCompletion() {
System.out.println("Import completed");
}
// 抽象方法 - 由子类实现
protected abstract void validate(String data);
protected abstract void parse(String data);
protected abstract void save(String data);
}
// 具体类
public class CsvImporter extends DataImporter {
protected void validate(String data) {
System.out.println("Validating CSV format");
}
protected void parse(String data) {
System.out.println("Parsing CSV data");
}
protected void save(String data) {
System.out.println("Saving CSV records");
}
}
// 用法
DataImporter importer = new CsvImporter();
importer.importData("data.csv"); // 执行完整工作流
将操作与对象结构分离。
// 元素
public interface Shape {
void accept(ShapeVisitor visitor);
}
// 具体元素
public class Circle implements Shape {
private double radius;
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
public double getRadius() { return radius; }
}
public class Rectangle implements Shape {
private double width, height;
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
public double getWidth() { return width; }
public double getHeight() { return height; }
}
// 访问者
public interface ShapeVisitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
// 具体访问者
public class AreaCalculator implements ShapeVisitor {
private double totalArea;
public void visit(Circle circle) {
totalArea += Math.PI * circle.getRadius() * circle.getRadius();
}
public void visit(Rectangle rectangle) {
totalArea += rectangle.getWidth() * rectangle.getHeight();
}
public double getTotalArea() { return totalArea; }
}
// 另一个访问者
public class ShapeDrawer implements ShapeVisitor {
public void visit(Circle circle) {
System.out.println("Drawing circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Drawing rectangle");
}
}
// 用法
List<Shape> shapes = Arrays.asList(new Circle(), new Rectangle());
AreaCalculator calculator = new AreaCalculator();
for (Shape shape : shapes) {
shape.accept(calculator);
}
System.out.println("Total area: " + calculator.getTotalArea());
ShapeDrawer drawer = new ShapeDrawer();
for (Shape shape : shapes) {
shape.accept(drawer);
}
PropertyChangeListener 或响应式流(RxJava, Project Reactor)每周安装数
1
仓库
GitHub 星标数
1
首次出现
1 天前
安全审计
安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
Quick reference for all Gang of Four design patterns in Java.
| Pattern | Use When | Don't Use When |
|---|---|---|
| Singleton | Exactly one instance needed (DB connection, cache) | Multiple instances needed, testing is hard |
| Factory Method | Delegate instantiation to subclasses | Single product type, simple creation |
| Abstract Factory | Create families of related objects | Single products, product types change often |
| Builder | Many optional params, step-by-step construction | Few params, simple objects |
| Prototype | Creating objects is expensive, clone existing | Objects are simple, deep cloning is complex |
| Pattern | Use When | Don't Use When |
|---|---|---|
| Adapter | Interface incompatible with client | Interfaces already compatible |
| Bridge | Abstraction and implementation vary independently | Simple hierarchy, few variations |
| Composite | Tree structure, treat individual and groups uniformly | No hierarchy, leaf-only structure |
| Decorator | Add responsibilities dynamically | Many decorators cause confusion |
| Facade | Simplify complex subsystem interface | Simple subsystem, direct access needed |
| Flyweight | Many similar objects, share state to save memory | Few objects, distinct states |
| Proxy | Control access, lazy loading, logging | Simple object access, adds unnecessary complexity |
| Pattern | Use When | Don't Use When |
|---|---|---|
| Chain of Responsibility | Multiple handlers, dynamic chain | Chain is fixed, simple handling |
| Command | Queue/undo operations, decouple sender/receiver | Simple direct calls, no undo needed |
| Iterator | Traverse collection without exposing internals | Simple collections, Java's Iterator sufficient |
| Mediator | Complex communication between many objects | Few objects, simple interactions |
| Memento | Save/restore object state (undo) | State is simple, or persistence not needed |
| Observer | One-to-many dependency, event subscription | No notification needed, tight coupling OK |
| State | Object behavior changes based on state |
Ensure a class has only one instance with global access.
// Thread-Safe Singleton with Double-Checked Locking
public final class DatabaseConnection {
private static volatile DatabaseConnection instance;
private DatabaseConnection() {
// private constructor
}
public static DatabaseConnection getInstance() {
if (instance == null) {
synchronized (DatabaseConnection.class) {
if (instance == null) {
instance = new DatabaseConnection();
}
}
}
return instance;
}
}
// Alternative: Enum Singleton (serialization-safe, reflection-safe)
public enum EnumSingleton {
INSTANCE;
public void doSomething() {
// business logic
}
}
Use for: DB connections, caches, thread pools, configuration
Create objects without specifying exact class.
// Product Interface
public interface Notification {
void send(String message);
}
// Concrete Products
public class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
public class SmsNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
// Creator
public abstract class NotificationFactory {
abstract Notification createNotification();
public void notifyUser(String message) {
Notification notification = createNotification();
notification.send(message);
}
}
// Concrete Creators
public class EmailNotificationFactory extends NotificationFactory {
Notification createNotification() {
return new EmailNotification();
}
}
// Usage
NotificationFactory factory = new EmailNotificationFactory();
factory.notifyUser("Hello!");
Create families of related objects.
// Abstract Factory
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Concrete Factories
public class WindowsFactory implements GUIFactory {
public Button createButton() { return new WindowsButton(); }
public Checkbox createCheckbox() { return new WindowsCheckbox(); }
}
public class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Checkbox createCheckbox() { return new MacCheckbox(); }
}
// Usage
GUIFactory factory = System.getProperty("os.name").contains("Windows")
? new WindowsFactory() : new MacFactory();
Button button = factory.createButton();
Construct complex objects step by step.
// With Lombok (Recommended)
@Data
@Builder
public class User {
private String id;
private String email;
private String name;
private int age;
private String address;
}
// Usage
User user = User.builder()
.id("123")
.email("user@example.com")
.name("John")
.build();
// Manual Implementation
public class UserBuilder {
private User user = new User();
public UserBuilder withEmail(String email) {
user.setEmail(email);
return this;
}
public UserBuilder withName(String name) {
user.setName(name);
return this;
}
public User build() {
// validation
if (user.getEmail() == null) {
throw new IllegalStateException("Email is required");
}
return user;
}
}
Clone existing objects.
public interface Prototype<T> extends Cloneable {
T clone();
}
public class Document implements Prototype<Document> {
private String title;
private String content;
private List<String> tags;
// Deep copy
@Override
public Document clone() {
try {
Document cloned = (Document) super.clone();
cloned.tags = new ArrayList<>(this.tags); // deep copy list
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
// Usage
Document template = new Document("Template", "Content", Arrays.asList("tag1"));
Document copy = template.clone();
Convert interface to another expected by client.
// Target interface
public interface MediaPlayer {
void play(String filename);
}
// Adaptee (existing interface)
public interface AdvancedMediaPlayer {
void playMp4(String filename);
void playVlc(String filename);
}
// Adapter
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("mp4")) {
advancedPlayer = new Mp4Player();
}
}
public void play(String filename) {
advancedPlayer.playMp4(filename);
}
}
Separate abstraction from implementation.
// Implementation interface
public interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
// Concrete Implementations
public class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double r) {
System.out.printf("API1.circle at (%.2f,%.2f) radius %.2f%n", x, y, r);
}
}
// Abstraction
public abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI api) {
this.drawingAPI = api;
}
public abstract void draw();
}
// Refined Abstraction
public class CircleShape extends Shape {
private double x, y, radius;
public CircleShape(double x, double y, double r, DrawingAPI api) {
super(api);
this.x = x; this.y = y; this.radius = r;
}
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
// Usage
Shape circle = new CircleShape(1, 2, 3, new DrawingAPI1());
circle.draw();
Compose objects into tree structures.
// Component
public interface Employee {
void showEmployeeDetails();
double getSalary();
}
// Leaf
public class Developer implements Employee {
private String name;
private double salary;
public void showEmployeeDetails() {
System.out.println(name + " - " + salary);
}
public double getSalary() { return salary; }
}
// Composite
public class Manager implements Employee {
private String name;
private double salary;
private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee emp) {
employees.add(emp);
}
public void showEmployeeDetails() {
System.out.println(name + " - " + salary);
for (Employee emp : employees) {
emp.showEmployeeDetails();
}
}
public double getSalary() {
return salary + employees.stream().mapToDouble(Employee::getSalary).sum();
}
}
Add responsibilities dynamically.
// Component
public interface Coffee {
double getCost();
String getDescription();
}
// Concrete Component
public class SimpleCoffee implements Coffee {
public double getCost() { return 10; }
public String getDescription() { return "Simple coffee"; }
}
// Decorator
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
public double getCost() {
return decoratedCoffee.getCost();
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// Concrete Decorators
public class Milk extends CoffeeDecorator {
public Milk(Coffee coffee) { super(coffee); }
public double getCost() { return super.getCost() + 2; }
public String getDescription() { return super.getDescription() + ", milk"; }
}
// Usage
Coffee coffee = new SimpleCoffee();
coffee = new Milk(coffee);
coffee = new Sugar(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
Simplified interface to complex subsystem.
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 start() {
cpu.freeze();
memory.load(0, hardDrive.read(0, 1024));
cpu.jump(0);
cpu.execute();
}
public void shutdown() {
cpu.stop();
memory.clear();
}
}
// Usage - simple interface hides complexity
ComputerFacade computer = new ComputerFacade();
computer.start();
Share data to support large numbers of objects.
// Flyweight
public interface Character {
void display(int position);
}
// Concrete Flyweight (intrinsic state)
public class CharacterGlyph implements Character {
private char symbol; // shared
private String font; // shared
public CharacterGlyph(char symbol, String font) {
this.symbol = symbol;
this.font = font;
}
public void display(int position) { // extrinsic state
System.out.println(symbol + " at position " + position);
}
}
// Flyweight Factory
public class CharacterFactory {
private Map<String, Character> characters = new HashMap<>();
public Character getCharacter(char symbol, String font) {
String key = symbol + font;
return characters.computeIfAbsent(key,
k -> new CharacterGlyph(symbol, font));
}
}
Placeholder to control access.
// Subject
public interface Image {
void display();
}
// Real Subject
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading " + filename);
}
public void display() {
System.out.println("Displaying " + filename);
}
}
// Proxy
public 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); // lazy loading
}
realImage.display();
}
}
// Usage
Image image = new ProxyImage("photo.jpg"); // no loading yet
image.display(); // loads and displays
Pass requests along chain of handlers.
public abstract class Logger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected Logger nextLogger;
public void setNextLogger(Logger next) {
this.nextLogger = next;
}
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);
}
// Concrete Handlers
public class ConsoleLogger extends Logger {
public ConsoleLogger(int level) { this.level = level; }
protected void write(String message) {
System.out.println("Console: " + message);
}
}
// Usage - chain them together
Logger loggerChain = new ConsoleLogger(Logger.INFO);
Logger errorLogger = new ErrorLogger(Logger.ERROR);
loggerChain.setNextLogger(errorLogger);
loggerChain.logMessage(Logger.INFO, "Info message");
Encapsulate requests as objects.
// Command
public interface Command {
void execute();
void undo();
}
// Receiver
public class Light {
public void on() { System.out.println("Light is on"); }
public void off() { System.out.println("Light is off"); }
}
// Concrete Command
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); }
public void undo() { light.off(); }
}
// Invoker
public class RemoteControl {
private Command command;
public void setCommand(Command cmd) { this.command = cmd; }
public void pressButton() { command.execute(); }
public void pressUndo() { command.undo(); }
}
// Usage
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();
Traverse collection without exposing internals.
// Iterator
public interface Iterator<T> {
boolean hasNext();
T next();
}
// Aggregate
public interface Container<T> {
Iterator<T> getIterator();
}
// Concrete Collection
public class NameRepository implements Container<String> {
private String[] names = {"Robert", "John", "Julie"};
public Iterator<String> getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator<String> {
private int index;
public boolean hasNext() {
return index < names.length;
}
public String next() {
return hasNext() ? names[index++] : null;
}
}
}
// Usage - Java's enhanced for-loop uses Iterator internally
NameRepository repo = new NameRepository();
for (Iterator<String> it = repo.getIterator(); it.hasNext(); ) {
System.out.println(it.next());
}
Encapsulate how objects interact.
// Mediator
public interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// Concrete Mediator
public class ChatMediatorImpl implements ChatMediator {
private List<User> users = new ArrayList<>();
public void addUser(User user) {
users.add(user);
}
public void sendMessage(String msg, User sender) {
for (User user : users) {
if (user != sender) {
user.receive(msg);
}
}
}
}
// Colleague
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name) {
this.mediator = med;
this.name = name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
// Concrete Colleague
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
public void send(String msg) {
System.out.println(name + ": Sending Message=" + msg);
mediator.sendMessage(msg, this);
}
public void receive(String msg) {
System.out.println(name + ": Received Message=" + msg);
}
}
// Usage
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "John");
User user2 = new UserImpl(mediator, "Jane");
mediator.addUser(user1);
mediator.addUser(user2);
user1.send("Hi Jane!");
Capture and restore object state.
// Memento
public class EditorMemento {
private final String content;
private final LocalDateTime savedAt;
public EditorMemento(String content) {
this.content = content;
this.savedAt = LocalDateTime.now();
}
public String getContent() { return content; }
}
// Originator
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) {
content = memento.getContent();
}
}
// Caretaker
public class History {
private List<EditorMemento> mementos = new ArrayList<>();
private Editor editor;
public History(Editor editor) {
this.editor = editor;
}
public void backup() {
mementos.add(editor.save());
}
public void undo() {
if (!mementos.isEmpty()) {
EditorMemento memento = mementos.remove(mementos.size() - 1);
editor.restore(memento);
}
}
}
// Usage
Editor editor = new Editor();
History history = new History(editor);
editor.setContent("Version 1");
history.backup();
editor.setContent("Version 2");
history.undo(); // Restores to "Version 1"
Define one-to-many dependency.
// Observer
public interface StockObserver {
void update(String stockSymbol, double price);
}
// Subject
public interface StockSubject {
void registerObserver(StockObserver observer);
void removeObserver(StockObserver observer);
void notifyObservers();
}
// Concrete Subject
public class StockPrice implements StockSubject {
private List<StockObserver> observers = new ArrayList<>();
private String symbol;
private double price;
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
public void registerObserver(StockObserver observer) {
observers.add(observer);
}
public void notifyObservers() {
for (StockObserver observer : observers) {
observer.update(symbol, price);
}
}
}
// Concrete Observer
public class MobileApp implements StockObserver {
public void update(String symbol, double price) {
System.out.println("MobileApp: " + symbol + " is now $" + price);
}
}
// Usage with Java's built-in (java.util.Observer is deprecated, use PropertyChangeListener)
StockPrice stock = new StockPrice();
stock.registerObserver(new MobileApp());
stock.registerObserver(new WebApp());
stock.setPrice(150.00); // Notifies all observers
Alter behavior when state changes.
// State
public interface VendingMachineState {
void insertMoney();
void ejectMoney();
void dispense();
}
// Concrete States
public class NoMoneyState implements VendingMachineState {
private VendingMachine machine;
public NoMoneyState(VendingMachine machine) {
this.machine = machine;
}
public void insertMoney() {
System.out.println("Money inserted");
machine.setState(machine.getHasMoneyState());
}
public void ejectMoney() {
System.out.println("No money to eject");
}
public void dispense() {
System.out.println("Insert money first");
}
}
// Context
public class VendingMachine {
private VendingMachineState noMoneyState;
private VendingMachineState hasMoneyState;
private VendingMachineState currentState;
public VendingMachine() {
noMoneyState = new NoMoneyState(this);
hasMoneyState = new HasMoneyState(this);
currentState = noMoneyState;
}
public void setState(VendingMachineState state) {
this.currentState = state;
}
public void insertMoney() { currentState.insertMoney(); }
public void ejectMoney() { currentState.ejectMoney(); }
public void dispense() { currentState.dispense(); }
public VendingMachineState getNoMoneyState() { return noMoneyState; }
public VendingMachineState getHasMoneyState() { return hasMoneyState; }
}
Family of algorithms, interchangeable.
// Strategy
public interface PaymentStrategy {
void pay(int amount);
}
// Concrete Strategies
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card " + cardNumber);
}
}
public class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal " + email);
}
}
// Context
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
// Usage
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new CreditCardPayment("1234-5678"));
cart.checkout(100);
cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
cart.checkout(50);
Algorithm skeleton in base class.
// Abstract Class with Template Method
public abstract class DataImporter {
// Template method - defines the algorithm
public final void importData(String filePath) {
String data = readFile(filePath);
validate(data);
parse(data);
save(data);
notifyCompletion();
}
// Concrete methods
protected String readFile(String filePath) {
// Common implementation
return "file content";
}
protected void notifyCompletion() {
System.out.println("Import completed");
}
// Abstract methods - implemented by subclasses
protected abstract void validate(String data);
protected abstract void parse(String data);
protected abstract void save(String data);
}
// Concrete Class
public class CsvImporter extends DataImporter {
protected void validate(String data) {
System.out.println("Validating CSV format");
}
protected void parse(String data) {
System.out.println("Parsing CSV data");
}
protected void save(String data) {
System.out.println("Saving CSV records");
}
}
// Usage
DataImporter importer = new CsvImporter();
importer.importData("data.csv"); // Executes full workflow
Separate operations from objects.
// Element
public interface Shape {
void accept(ShapeVisitor visitor);
}
// Concrete Elements
public class Circle implements Shape {
private double radius;
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
public double getRadius() { return radius; }
}
public class Rectangle implements Shape {
private double width, height;
public void accept(ShapeVisitor visitor) {
visitor.visit(this);
}
public double getWidth() { return width; }
public double getHeight() { return height; }
}
// Visitor
public interface ShapeVisitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
// Concrete Visitor
public class AreaCalculator implements ShapeVisitor {
private double totalArea;
public void visit(Circle circle) {
totalArea += Math.PI * circle.getRadius() * circle.getRadius();
}
public void visit(Rectangle rectangle) {
totalArea += rectangle.getWidth() * rectangle.getHeight();
}
public double getTotalArea() { return totalArea; }
}
// Another Visitor
public class ShapeDrawer implements ShapeVisitor {
public void visit(Circle circle) {
System.out.println("Drawing circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Drawing rectangle");
}
}
// Usage
List<Shape> shapes = Arrays.asList(new Circle(), new Rectangle());
AreaCalculator calculator = new AreaCalculator();
for (Shape shape : shapes) {
shape.accept(calculator);
}
System.out.println("Total area: " + calculator.getTotalArea());
ShapeDrawer drawer = new ShapeDrawer();
for (Shape shape : shapes) {
shape.accept(drawer);
}
PropertyChangeListener or reactive streams (RxJava, Project Reactor)Weekly Installs
1
Repository
GitHub Stars
1
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
111,800 周安装
| Few states, simple conditions suffice |
| Strategy | Multiple algorithms, interchangeable | Single algorithm, no variation |
| Template Method | Common algorithm with variant steps | Algorithm varies completely |
| Visitor | Separate operations from object structure | Structure changes often, few operations |