常见Java设计模式&Agent设计模式

常见 Java 设计模式 & Agent 设计模式

一、Java 常见设计模式

1. 单例模式(Singleton)

名词解释:确保一个类只有一个实例,并提供全局访问点。核心三要素:私有构造函数、静态实例变量、公共获取方法。适用于配置管理器、连接池、日志器等全局唯一资源。

public class Singleton {
    // volatile 防止指令重排序导致的双重检查锁失效
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {                  // 第一次检查(无锁)
            synchronized (Singleton.class) {
                if (instance == null) {          // 第二次检查(有锁)
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

2. 工厂方法模式(Factory Method)

名词解释:定义创建对象的接口,但将实际实例化延迟到子类。调用方无需知道具体类名,只需面向抽象工厂编程。适用于对象创建逻辑复杂或需要根据条件动态选择实现类的场景。

interface Notification {
    void send(String message);
}

class EmailNotification implements Notification {
    public void send(String message) { System.out.println("Email: " + message); }
}

class SmsNotification implements Notification {
    public void send(String message) { System.out.println("SMS: " + message); }
}

class NotificationFactory {
    public static Notification create(String type) {
        return switch (type) {
            case "email" -> new EmailNotification();
            case "sms"   -> new SmsNotification();
            default -> throw new IllegalArgumentException("Unknown type: " + type);
        };
    }
}

3. 策略模式(Strategy)

名词解释:将一组可互换的算法封装为独立类,使它们可以相互替换,算法的变化不影响使用它的客户端。核心是"面向接口编程 + 组合优于继承"。适用于支付方式选择、排序策略切换、RAG 检索策略等场景。

interface PayStrategy {
    void pay(double amount);
}

class AlipayStrategy implements PayStrategy {
    public void pay(double amount) { System.out.println("支付宝支付: " + amount); }
}

class WechatPayStrategy implements PayStrategy {
    public void pay(double amount) { System.out.println("微信支付: " + amount); }
}

class PaymentContext {
    private final PayStrategy strategy;

    public PaymentContext(PayStrategy strategy) { this.strategy = strategy; }

    public void executePayment(double amount) { strategy.pay(amount); }
}
// 使用: new PaymentContext(new AlipayStrategy()).executePayment(99.9);

4. 观察者模式(Observer)

名词解释:定义对象间一对多的依赖关系,当被观察对象状态改变时,所有观察者自动收到通知并更新。解耦了事件源与事件处理逻辑。适用于消息队列消费、Spring EventListener、UI 事件绑定等场景。

interface EventListener {
    void onEvent(String event);
}

class EventBus {
    private final List<EventListener> listeners = new CopyOnWriteArrayList<>();

    public void subscribe(EventListener listener) { listeners.add(listener); }

    public void publish(String event) {
        for (EventListener listener : listeners) {
            listener.onEvent(event);
        }
    }
}
// 使用:
// EventBus bus = new EventBus();
// bus.subscribe(event -> System.out.println("收到事件: " + event));
// bus.publish("ORDER_CREATED");

5. 代理模式(Proxy)

名词解释:为另一个对象提供替代/占位符,控制对该对象的访问。常见类型:静态代理、JDK 动态代理、CGLIB 代理。适用于 AOP 切面、RPC 远程调用、缓存代理、权限校验等场景。

interface UserService {
    String getUser(long userId);
}

class UserServiceImpl implements UserService {
    public String getUser(long userId) { return "User-" + userId; }
}

class LoggingProxy implements InvocationHandler {
    private final Object target;

    LoggingProxy(Object target) { this.target = target; }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("[LOG] 调用: " + method.getName());
        long start = System.currentTimeMillis();
        Object result = method.invoke(target, args);
        System.out.println("[LOG] 耗时: " + (System.currentTimeMillis() - start) + "ms");
        return result;
    }
}
// 创建代理:
// UserService proxy = (UserService) Proxy.newProxyInstance(
//     UserService.class.getClassLoader(),
//     new Class[]{UserService.class},
//     new LoggingProxy(new UserServiceImpl())
// );

PART1_EOF; __aone_exit=$?; pwd -P > '/var/folders/16/9_zfgr597913w07fgnz50grc0000gn/T/aone-copilot-cwd-1782194742926-afn8ybnm2t7.txt' 2>/dev/null; exit $__aone_exit

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

名词解释:在父类中定义算法骨架,将某些步骤延迟到子类实现,子类可以在不改变算法结构的前提下重写特定步骤。核心是"固定流程 + 可变细节"。适用于审批流、数据导入导出、单元测试 setUp/tearDown 等场景。

abstract class AbstractDataExport {
    // 模板方法(final 防止子类篡改流程)
    public final void export() {
        validate();
        List<String> data = queryData();
        String content = format(data);
        save(content);
    }

    protected abstract List<String> queryData();
    protected abstract String format(List<String> data);

    protected void validate() { System.out.println("参数校验通过"); }
    protected void save(String content) { System.out.println("保存: " + content.length() + " chars"); }
}

class ExcelExport extends AbstractDataExport {
    protected List<String> queryData() { return List.of("row1", "row2"); }
    protected String format(List<String> data) { return String.join(",", data); }
}

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

名词解释:将请求沿处理者链传递,每个处理者决定自己处理还是传给下一个。解耦了发送者与接收者,支持动态组装处理顺序。适用于 Servlet Filter、Spring Interceptor、审批流多级审核、Agent Tool 路由等场景。

abstract class Handler {
    private Handler next;

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

    public void handle(Request request) {
        if (canHandle(request)) {
            doHandle(request);
        } else if (next != null) {
            next.handle(request);
        } else {
            System.out.println("无处理器匹配: " + request.getType());
        }
    }

    protected abstract boolean canHandle(Request request);
    protected abstract void doHandle(Request request);
}

class AuthHandler extends Handler {
    protected boolean canHandle(Request r) { return "auth".equals(r.getType()); }
    protected void doHandle(Request r) { System.out.println("鉴权处理"); }
}

class BusinessHandler extends Handler {
    protected boolean canHandle(Request r) { return "biz".equals(r.getType()); }
    protected void doHandle(Request r) { System.out.println("业务处理"); }
}
// 组装: new AuthHandler().setNext(new BusinessHandler()).handle(new Request("biz"));

8. 装饰器模式(Decorator)

名词解释:动态地给对象添加额外职责,比继承更灵活。装饰器和被装饰对象实现同一接口,通过组合层层包裹。适用于 IO 流嵌套(BufferedInputStream)、Spring BeanWrapper、缓存/限流/日志等横切增强。

interface DataSource {
    String readData();
    void writeData(String data);
}

class FileDataSource implements DataSource {
    private final String filename;
    FileDataSource(String f) { this.filename = f; }
    public String readData() { return "file:" + filename; }
    public void writeData(String data) { System.out.println("写入文件: " + data); }
}

abstract class DataSourceDecorator implements DataSource {
    protected final DataSource wrappee;
    DataSourceDecorator(DataSource w) { this.wrappee = w; }
}

class EncryptionDecorator extends DataSourceDecorator {
    EncryptionDecorator(DataSource s) { super(s); }
    public String readData() { return "decrypt(" + wrappee.readData() + ")"; }
    public void writeData(String d) { wrappee.writeData("encrypt(" + d + ")"); }
}

class CompressionDecorator extends DataSourceDecorator {
    CompressionDecorator(DataSource s) { super(s); }
    public String readData() { return "decompress(" + wrappee.readData() + ")"; }
    public void writeData(String d) { wrappee.writeData("compress(" + d + ")"); }
}
// 自由组合: new CompressionDecorator(new EncryptionDecorator(new FileDataSource("data.txt")))

9. 适配器模式(Adapter)

名词解释:将一个类的接口转换为客户端期望的另一个接口,使原本不兼容的类能协同工作。分为类适配器(继承)和对象适配器(组合,推荐)。适用于第三方 SDK 接入、新旧系统对接、统一多数据源接口等场景。

interface TargetLogger {
    void log(String level, String message);
}

class LegacyLogger {
    public void writeLog(int severity, String msg) {
        System.out.println("[" + severity + "] " + msg);
    }
}

class LoggerAdapter implements TargetLogger {
    private final LegacyLogger legacy = new LegacyLogger();

    @Override
    public void log(String level, String message) {
        int severity = switch (level) {
            case "ERROR" -> 3;
            case "WARN"  -> 2;
            default      -> 1;
        };
        legacy.writeLog(severity, message);
    }
}

10. 建造者模式(Builder)

名词解释:将复杂对象的构建过程与其表示分离,允许分步设置属性并最终生成不可变对象。解决多参数构造函数的可读性和安全性问题。适用于 DTO/Config 构建、SQL 拼接、HTTP 请求构造等场景。

class HttpRequest {
    private final String url;
    private final String method;
    private final Map<String, String> headers;
    private final String body;
    private final int timeoutMs;

    private HttpRequest(Builder b) {
        this.url = b.url;
        this.method = b.method;
        this.headers = Collections.unmodifiableMap(b.headers);
        this.body = b.body;
        this.timeoutMs = b.timeoutMs;
    }

    static class Builder {
        private final String url;
        private String method = "GET";
        private Map<String, String> headers = new HashMap<>();
        private String body;
        private int timeoutMs = 3000;

        Builder(String url) { this.url = Objects.requireNonNull(url); }
        Builder method(String m) { this.method = m; return this; }
        Builder header(String k, String v) { this.headers.put(k, v); return this; }
        Builder body(String b) { this.body = b; return this; }
        Builder timeout(int ms) { this.timeoutMs = ms; return this; }
        HttpRequest build() { return new HttpRequest(this); }
    }
}
// 使用: new HttpRequest.Builder("/api/users").method("POST").body("{}").timeout(5000).build()

PART2_EOF; __aone_exit=$?; pwd -P > '/var/folders/16/9_zfgr597913w07fgnz50grc0000gn/T/aone-copilot-cwd-1782194759510-m1zdxoz579o.txt' 2>/dev/null; exit $__aone_exit

二、Agent 设计模式

Agent 设计模式是 LLM 应用工程化中沉淀出的架构范式,与传统 GoF 模式互补,专注于解决 LLM 不确定性、工具编排、多轮交互、自我纠错 等问题。

1. ReAct(Reasoning + Acting)

名词解释:让 LLM 交替进行"推理(Thought)→ 行动(Action)→ 观察(Observation)"三步循环,直到得出最终答案。是最基础的 Agent Loop 范式,解决了纯 CoT 无法与外部世界交互、纯 Function Calling 缺乏推理过程的问题。

def react_loop(user_input, tools, max_steps=10):
    history = []
    for _ in range(max_steps):
        response = llm.generate(
            prompt=f"{user_input}\n{format_history(history)}\n"
                   f"Think step by step. Output format:\n"
                   f"Thought: ...\nAction: tool_name(args)\nOR\nFinal Answer: ..."
        )
        if "Final Answer:" in response:
            return extract_final_answer(response)

        thought, action = parse_thought_action(response)
        observation = tools.execute(action)
        history.append((thought, action, observation))

    return "Max steps reached"

2. Reflection / Self-Critique

名词解释:Agent 在执行后对自己的输出进行反思和批评,发现错误后重新生成改进版本。本质是将"评估"作为 Loop 的一环,用 LLM 自身做 Judge。适用于代码生成后自测、文案润色、数学题验算等需要质量保障的场景。

def reflect_and_improve(task, initial_output, max_reflections=3):
    current = initial_output
    for i in range(max_reflections):
        critique = llm.generate(
            f"Task: {task}\nCurrent output:\n{current}\n\n"
            f"Critique this output. Identify errors and suggest improvements."
        )
        if "no issues" in critique.lower():
            break
        current = llm.generate(
            f"Task: {task}\nPrevious output:\n{current}\n"
            f"Critique:\n{critique}\n\nGenerate an improved version."
        )
    return current

3. Planning(计划-执行分离)

名词解释:将复杂任务先分解为有序子计划,再逐步执行每个子步骤。与 ReAct 的区别是"先想清楚再动手"而非"边想边做"。适用于多步骤长任务(如调研报告撰写、跨系统数据迁移),降低中途迷失方向的概率。

def plan_and_execute(task, tools):
    # Phase 1: 生成计划
    plan = llm.generate(
        f"Break down this task into ordered subtasks:\n{task}\nOutput as numbered list."
    )
    subtasks = parse_numbered_list(plan)

    # Phase 2: 逐步执行
    results = []
    for subtask in subtasks:
        result = react_loop(subtask, tools)
        results.append(result)

    # Phase 3: 汇总
    return llm.generate(f"Task: {task}\nSubtask results: {results}\nSynthesize final answer.")

4. Tool Use / Function Calling

名词解释:LLM 不直接执行操作,而是输出结构化的工具调用指令(函数名+参数),由外部运行时解析并执行后将结果回传。这是 Agent 与真实世界交互的标准协议。关键设计点:工具描述的清晰度直接影响 LLM 的选择准确率。

@Component
@ToolDefinition(
    name = "aiLeaveQuota",
    description = "查询员工假期剩余额度,输入工号返回各假期类型的剩余天数",
    parameters = {
        @Param(name = "empNo", description = "员工工号", required = true),
        @Param(name = "year", description = "查询年份,默认当年")
    }
)
public class AILeaveQuotaTool implements ToolExecutor {
    @Override
    public String execute(Map<String, Object> params) {
        String empNo = (String) params.get("empNo");
        int year = params.containsKey("year") ? (int) params.get("year") : Year.now().getValue();
        LeaveQuota quota = leaveService.queryQuota(empNo, year);
        return JsonUtils.toJson(quota);
    }
}

5. Multi-Agent Collaboration(多智能体协作)

名词解释:多个专职 Agent 各司其职,通过消息传递或共享状态协作完成复杂任务。常见拓扑:中心化调度(Orchestrator)、流水线(Pipeline)、辩论式(Debate)。适用于需要多种专业能力协同的场景,如"研究员+写手+审稿人"的内容生产链。

class Orchestrator:
    def __init__(self, agents: dict[str, Agent]):
        self.agents = agents

    def run(self, task):
        research = self.agents["researcher"].execute(f"Research: {task}")
        draft = self.agents["writer"].execute(f"Write based on:\n{research}")
        feedback = self.agents["reviewer"].execute(f"Review:\n{draft}")
        if "approve" not in feedback.lower():
            draft = self.agents["writer"].execute(f"Revise based on feedback:\n{feedback}")
        return draft

6. RAG(Retrieval-Augmented Generation)

名词解释:先从外部知识库检索相关文档片段,再将其作为上下文注入 LLM Prompt,使回答有据可依。解决了 LLM 知识截止、幻觉、私有数据缺失三大问题。关键环节:文档切片 → Embedding → 向量检索 → Rerank → 上下文组装。

public String ragAnswer(String userQuery) {
    // 1. Query 改写
    String rewrittenQuery = queryRewriter.rewrite(userQuery);
    // 2. 混合检索
    List<Document> vectorResults = vectorStore.search(rewrittenQuery, 5);
    List<Document> keywordResults = esClient.search(rewrittenQuery, 5);
    List<Document> merged = reciprocalRankFuse(vectorResults, keywordResults);
    // 3. Rerank
    List<Document> reranked = rerankModel.rerank(userQuery, merged, 3);
    // 4. 组装 Prompt 并生成
    String context = reranked.stream().map(Document::getContent)
        .collect(Collectors.joining("\n---\n"));
    return llm.chat(buildRagPrompt(userQuery, context));
}

7. Memory(记忆机制)

名词解释:为 Agent 提供跨轮次/跨会话的信息持久化能力。分为短期记忆(当前对话窗口)、长期记忆(向量库/结构化存储)、工作记忆(Scratchpad 暂存中间推理结果)。解决 LLM 上下文窗口有限和多轮对话一致性问题。

class AgentMemory:
    def __init__(self):
        self.short_term = []
        self.working_pad = ""
        self.long_term_store = VectorStore()

    def add_turn(self, role, content):
        self.short_term.append({"role": role, "content": content})
        if len(self.short_term) > 20:
            summary = llm.summarize(self.short_term[:10])
            self.short_term = [{"role": "system", "content": f"History summary: {summary}"}] \
                            + self.short_term[10:]

    def recall(self, query, top_k=3):
        return self.long_term_store.search(query, top_k)

    def consolidate(self):
        insights = llm.extract_insights(self.short_term)
        for insight in insights:
            self.long_term_store.upsert(insight)

三、Java 模式与 Agent 模式的映射关系

Java 设计模式 Agent 中的对应实践 说明
策略模式 RAG 检索策略切换(向量/关键词/混合) 不同检索算法可插拔替换
责任链模式 Agent Tool 路由 / PreInterceptor 链 请求沿链路匹配处理器
观察者模式 Agent 事件驱动(Tool 执行回调、流式输出) 异步通知解耦
模板方法模式 Agent Loop 骨架(ReAct / Plan-Execute) 固定循环结构,可变推理/工具步骤
装饰器模式 Prompt 增强链(System Prompt + Memory + Tools) 层层包裹构建最终 Prompt
工厂模式 Tool 实例化 / LLM Provider 切换 根据配置动态创建组件
代理模式 LLM 调用代理(重试、限流、日志、缓存) 透明增强 LLM 调用
建造者模式 Prompt 构建 / Agent Config 组装 分步构造复杂配置对象
PART3_EOF; __aone_exit=$?; pwd -P > '/var/folders/16/9_zfgr597913w07fgnz50grc0000gn/T/aone-copilot-cwd-1782194791544-5r369zaitpb.txt' 2>/dev/null; exit $__aone_exit
posted @ 2026-06-23 14:08  cwp0  阅读(1)  评论(0)    收藏  举报