构建设计模式字典

news/2025/12/6 0:14:00/文章来源:https://www.cnblogs.com/xtkyxnx/p/19314147

关联知识库:构建设计模式字典

设计模式字典 - 中文版

https://draveness.me/holy-grail-design-pattern/

https://www.cnblogs.com/wxdlut/p/17346906.html

https://developer.aliyun.com/article/342530

https://www.infoq.cn/article/design-patterns-proposed-by-gof-20-years-ago

关于设计模式的争议

近年来,关于设计模式的争论非常激烈。

理解和学习它是第一步(如果你想谈论它,无论你站在哪一边)。

站在巨人的肩膀上无疑是一个明智的选择。作为经验的汇集,无疑见证了前辈们是如何运用面向对象编程(OOP)思想的。这23篇经验汇集展现了一段辉煌的历史。

如何应用它是第二步,而分歧也由此而来。
有些人将设计模式奉为天堂,认为它们是最佳实践,并被广泛使用。
另一些人则将设计模式贬低为地狱,认为它们不过是过去的糟粕,并不适用于当下。
当然,大多数人持中立态度。

尽信书不如无书。追求低耦合,但不可能完全没有耦合。

首先,在实际应用中考虑使用设计模式并没有错。这只是利用现有的解决方案来解决现有的问题。

然而,在分析和处理问题时,并不应该局限于设计模式。设计模式是面向对象编程(OOP)思维的最佳实践,也就是说,OOP 的落地经验产生了设计模式。

面对实际问题时,OOP 思维应该是第一反应。在 OOP 思维下,问题才有一个对应的上下文。这些上下文就是设计模式的源泉。同时,可以考虑当前问题是否与设计模式中已经解决的问题相匹配。

OOP和设计模式的比喻:乘法规则 / 25*25 = 625

接下来,也是最重要的一步 —— 平衡 与取舍
这是把握设计与过度设计的关键一步,关键在于利大于弊

设计模式并不能解决所有问题,反而会带来新的问题。但如果解决问题的价值大于新问题的弊端,那就使用它。

这条规则似乎不仅限于设计模式,所有方法论都适用。动态地分析问题处理方式的优劣,是为了达到一个准确合理的终点。

创建对象的模式

单例模式

全局唯一;通过添加类似 @Component 的注解,Spring bean 的作用域为单例。

原型模式

通过复制旧对象创建对象;为 Spring bean 设置 @Scope("prototype")。

建造者模式

使用建造者模式创建复杂对象,无需在构造函数中传递大量参数;为对象添加 Lombok 的 @Builder 注解。

工厂模式

封装一组或多组对象的创建过程,并提供统一的参数化对象创建入口。[结合策略模式实现]

  • 工厂方法
  • 抽象工厂 —— 工厂的工厂

对象行为模式

策略模式

背景:对于对象的单一行为,在不同场景下会有不同的实现。

思路:添加策略层(策略接口),解耦程序调用与实现,实现程序的可扩展性。

Implemention: https://github.com/qiao-925/Strategy-pattern-demo

模板模式

背景:对于一组操作,大多数步骤相同,只有少数步骤不同,这将产生大量重复代码。

思路:定义程序的框架,并将部分步骤推迟到子类中,以实现模板代码复用。

观察者模式

对象级别的 MQ。

专注于对象级别的事件发布和消息通知

职责链模式

根据单一职责原则,将复杂的业务处理流程拆分成链表结构,以实现可读性和可扩展性。

命令模式

解耦请求发送者和接收者。

  • code example

    // 命令接口
    public interface Command {void execute();
    }// 接收者
    public class Light {public void turnOn() {System.out.println("The light is on.");}public void turnOff() {System.out.println("The light is off.");}
    }// 具体命令:打开灯
    public class TurnOnLightCommand implements Command {private Light light;public TurnOnLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOn();}
    }// 具体命令:关闭灯
    public class TurnOffLightCommand implements Command {private Light light;public TurnOffLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}
    }// 调用者
    public class RemoteControl {private Command command;public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute(); // 执行命令}
    }public class Client {public static void main(String[] args) {Light light = new Light(); // 创建接收者Command turnOn = new TurnOnLightCommand(light); // 创建打开灯的命令Command turnOff = new TurnOffLightCommand(light); // 创建关闭灯的命令RemoteControl remote = new RemoteControl(); // 创建调用者// 打开灯remote.setCommand(turnOn);remote.pressButton();// 关闭灯remote.setCommand(turnOff);remote.pressButton();}
    }
    

备忘录模式

目标:用于对象的历史记录和备份。

示例:用于编辑器,记录和恢复历史状态。

  • code example

    public class Originator {private String state;public Originator(String state) {this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}
    /**
    * right here
    **/**public Memento createMemento() {return new Memento(state);}public void restoreMemento(Memento memento) {this.state = memento.getState();}**// Inner class for Mementopublic static class Memento {private final String state;public Memento(String state) {this.state = state;}public String getState() {return state;}}
    }
    

关于此模式,讨论的是:

如何在不破坏封装性的情况下公开私有成员变量数据?

当然,从私有变为公共很容易,但这会破坏封装性。

解决方案:对象本身保留创建备份的功能。

顺便说一句,这与充血模型的思维相关。

备忘录模式和充血模型比较 —— from manus

https://refactoringguru.cn/design-patterns/memento

状态模式

为每个状态及其行为创建类,以减少超过 3 个“if/else”语句的复杂性。

更易读、更易于维护,但类太多。

  • comparation

    normal implemention:

    public class ContentWithoutState {private String status = "草稿"; // 初始状态为草稿public void publish() {if (status.equals("草稿")) {status = "待发布";System.out.println("内容已提交待发布");} else if (status.equals("待发布")) {// 模拟发布过程,可能成功或失败boolean success = Math.random() < 0.8; // 80%概率成功if (success) {status = "已发布";System.out.println("内容发布成功");} else {status = "发布失败";System.out.println("内容发布失败");}} else {System.out.println("内容状态不允许发布");}}public String getStatus() {return status;}public static void main(String[] args) {ContentWithoutState content = new ContentWithoutState();content.publish();System.out.println("当前状态: " + content.getStatus());content.publish();System.out.println("当前状态: " + content.getStatus());content.publish();System.out.println("当前状态: " + content.getStatus());}
    }
    

    implementiom by state pattern

    interface ContentStatus {void publish(Content content);
    }class DraftStatus implements ContentStatus {@Overridepublic void publish(Content content) {System.out.println("内容已提交待发布");content.setStatus(content.getPendingStatus());}
    }class PendingStatus implements ContentStatus {@Overridepublic void publish(Content content) {boolean success = Math.random() < 0.8; // 80%概率成功if (success) {System.out.println("内容发布成功");content.setStatus(content.getPublishedStatus());} else {System.out.println("内容发布失败");content.setStatus(content.getFailedStatus());}}
    }class PublishedStatus implements ContentStatus {@Overridepublic void publish(Content content) {System.out.println("内容已发布,无法再次发布");}
    }class FailedStatus implements ContentStatus {@Overridepublic void publish(Content content) {System.out.println("内容发布失败,请检查错误并重新提交");}
    }public class ContentWithState {private ContentStatus status;private DraftStatus draftStatus = new DraftStatus();private PendingStatus pendingStatus = new PendingStatus();private PublishedStatus publishedStatus = new PublishedStatus();private FailedStatus failedStatus = new FailedStatus();public ContentWithState() {this.status = draftStatus;}public void publish() {status.publish(this);}public void setStatus(ContentStatus status) {this.status = status;}public ContentStatus getDraftStatus() { return draftStatus; }public ContentStatus getPendingStatus() { return pendingStatus; }public ContentStatus getPublishedStatus() { return publishedStatus; }public ContentStatus getFailedStatus() { return failedStatus; }public static void main(String[] args) {ContentWithState content = new ContentWithState();content.publish();content.publish();content.publish();}
    }
    

访问者模式

将数据结构与作用于它们的算法分离。

  • Example by json operations:

    import org.json.JSONObject;interface JsonVisitor {void visit(JSONObject jsonObject);
    }class PrintJsonVisitor implements JsonVisitor {@Overridepublic void visit(JSONObject jsonObject) {System.out.println("Name: " + jsonObject.getString("name"));System.out.println("Age: " + jsonObject.getInt("age"));System.out.println("City: " + jsonObject.getString("city"));}
    }class AgeSquareJsonVisitor implements JsonVisitor {@Overridepublic void visit(JSONObject jsonObject) {int age = jsonObject.getInt("age");System.out.println("Age squared: " + age * age);}
    }class AgePlusTenJsonVisitor implements JsonVisitor {@Overridepublic void visit(JSONObject jsonObject) {int age = jsonObject.getInt("age");System.out.println("Age plus 10: " + (age + 10));}
    }public class JsonWithVisitor {public static void main(String[] args) {String jsonString = "{\"name\":\"Alice\",\"age\":30,\"city\":\"New York\"}";JSONObject jsonObject = new JSONObject(jsonString);JsonVisitor printVisitor = new PrintJsonVisitor();printVisitor.visit(jsonObject);JsonVisitor ageSquareVisitor = new AgeSquareJsonVisitor();ageSquareVisitor.visit(jsonObject);JsonVisitor agePlusTenVisitor = new AgePlusTenJsonVisitor();agePlusTenVisitor.visit(jsonObject);}
    }
    

中介者模式

背景:多个对象之间存在大量的相互依赖关系。

其理念与 IOC 非常相似:将对象之间的对话转换为中介者与对象之间的对话。

对象结构模式

适配器模式

添加适配层来解决接口不兼容问题。

专注于接口层面。

桥接模式

延迟实例化和绑定。

使用组合模式代替继承模式,以避免类的排列组合导致的数量激增。

```jsx
// Implementor interface
interface MessageSender {void sendMessage(String message);
}// Concrete Implementors
class EmailSender implements MessageSender {@Overridepublic void sendMessage(String message) {System.out.println("Sending email: " + message);}
}class SmsSender implements MessageSender {@Overridepublic void sendMessage(String message) {System.out.println("Sending SMS: " + message);}
}// Abstraction
abstract class Message {protected MessageSender sender;Message(MessageSender sender) {this.sender = sender;}abstract void send(String message);
}// Refined Abstractions
class UrgentMessage extends Message {UrgentMessage(MessageSender sender) {super(sender);}@Overridevoid send(String message) {sender.sendMessage("URGENT: " + message);}
}class NormalMessage extends Message {NormalMessage(MessageSender sender) {super(sender);}@Overridevoid send(String message) {sender.sendMessage(message);}
}// Client code
public class BridgePatternDemo {public static void main(String[] args) {MessageSender emailSender = new EmailSender();MessageSender smsSender = new SmsSender();Message urgentEmail = new UrgentMessage(emailSender);urgentEmail.send("Meeting at 2 PM");Message normalSms = new NormalMessage(smsSender);normalSms.send("Reminder: Grocery shopping");}
}
```

组合模式

为客户端屏蔽对象和组合对象的具体实现提供统一的处理接口。

```jsx
// 抽象组件
public abstract class TreeNode {protected Long id;protected Long parentId;protected String name;protected Integer level;protected Integer sort;// 子节点操作public abstract void add(TreeNode node);public abstract void remove(TreeNode node);public abstract List<TreeNode> getChildren();// 树形结构操作public abstract List<TreeNode> getPath();public abstract boolean isLeaf();public abstract int getDepth();
}// 叶子节点
public class TreeLeaf extends TreeNode {@Overridepublic void add(TreeNode node) {throw new UnsupportedOperationException("Leaf node cannot add child");}@Overridepublic void remove(TreeNode node) {throw new UnsupportedOperationException("Leaf node cannot remove child");}@Overridepublic List<TreeNode> getChildren() {return Collections.emptyList();}@Overridepublic List<TreeNode> getPath() {return Collections.singletonList(this);}@Overridepublic boolean isLeaf() {return true;}@Overridepublic int getDepth() {return 0;}
}// 分支节点
public class TreeBranch extends TreeNode {private List<TreeNode> children = new ArrayList<>();@Overridepublic void add(TreeNode node) {children.add(node);}@Overridepublic void remove(TreeNode node) {children.remove(node);}@Overridepublic List<TreeNode> getChildren() {return Collections.unmodifiableList(children);}@Overridepublic List<TreeNode> getPath() {List<TreeNode> path = new ArrayList<>();path.add(this);if (!children.isEmpty()) {path.addAll(children.get(0).getPath());}return path;}@Overridepublic boolean isLeaf() {return children.isEmpty();}@Overridepublic int getDepth() {if (children.isEmpty()) {return 0;}return 1 + children.stream().mapToInt(TreeNode::getDepth).max().orElse(0);}
}
```

装饰器模式

动态地为对象添加一些额外的职责。

```jsx
// 组件接口
public interface Coffee {double cost();String getDescription();
}// 具体组件
public class SimpleCoffee implements Coffee {@Overridepublic double cost() {return 2.0; // 基础咖啡价格}@Overridepublic String getDescription() {return "Simple Coffee"; // 描述}
}----------------------------------------------------------------// 装饰器
public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 持有一个Coffee对象public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}
}// 具体装饰器:牛奶
public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic double cost() {return coffee.cost() + 0.5; // 加牛奶的额外费用}@Overridepublic String getDescription() {return coffee.getDescription() + ", Milk"; // 添加描述}
}// 具体装饰器:糖
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double cost() {return coffee.cost() + 0.2; // 加糖的额外费用}@Overridepublic String getDescription() {return coffee.getDescription() + ", Sugar"; // 添加描述}
}---------------------------------------------------------------------------------------public class CoffeeShop {public static void main(String[] args) {Coffee coffee = new SimpleCoffee(); // 创建基础咖啡System.out.println(coffee.getDescription() + " $" + coffee.cost());// 添加牛奶装饰coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());// 添加糖装饰coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());}
}
```

外观模式

封装子系统功能并提供简单的接口调用。

  • 计算机启动示例

    // 子系统类1
    public class CPU {public void freeze() {System.out.println("CPU is freezing.");}public void jump(long position) {System.out.println("CPU is jumping to: " + position);}public void execute() {System.out.println("CPU is executing.");}
    }// 子系统类2
    public class Memory {public void load(long position, byte[] data) {System.out.println("Memory is loading data at position: " + position);}
    }// 子系统类3
    public class HardDrive {public byte[] read(long lba, int size) {System.out.println("HardDrive is reading data from LBA: " + lba + ", size: " + size);return new byte[size]; // 返回模拟数据}
    }// 外观类
    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.freeze();memory.load(0, hardDrive.read(0, 1024));cpu.jump(0);cpu.execute();}
    }public class Client {public static void main(String[] args) {ComputerFacade computer = new ComputerFacade();computer.startComputer(); // 启动计算机}
    }
    

享元模式

也称为: 缓存

通过构建映射实现对象重用。

```jsx
// 享元接口
public interface Shape {void draw(String color);
}// 具体享元类
public class Circle implements Shape {private String type; // 内部状态public Circle() {this.type = "Circle"; // 共享的状态}@Overridepublic void draw(String color) {System.out.println("Drawing a " + color + " " + type);}
}// 享元工厂
import java.util.HashMap;
import java.util.Map;public class ShapeFactory {private Map<String, Shape> shapes = new HashMap<>();public Shape getCircle(String color) {Shape circle = shapes.get(color);if (circle == null) {circle = new Circle();shapes.put(color, circle);System.out.println("Creating a new circle of color: " + color);}return circle;}
}// 客户端代码
public class Client {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();// 创建并使用享元对象Shape redCircle = shapeFactory.getCircle("Red");redCircle.draw("Red");Shape greenCircle = shapeFactory.getCircle("Green");greenCircle.draw("Green");// 共享相同的对象Shape anotherRedCircle = shapeFactory.getCircle("Red");anotherRedCircle.draw("Red");// 输出结果System.out.println("Red circle and another red circle are the same object: " + (redCircle == anotherRedCircle));}
}
```

代理模式

创建一个代理对象来控制对真实对象的调用,以实现额外的功能。

```jsx
// 主题接口
public interface Subject {void request();
}// 真实对象
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}// 代理对象
public class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject(); // 延迟加载}// 代理的额外功能System.out.println("Proxy: Pre-processing request.");realSubject.request(); // 调用真实对象的方法System.out.println("Proxy: Post-processing request.");}
}// 客户端代码
public class Client {public static void main(String[] args) {Subject subject = new Proxy(); // 使用代理对象subject.request(); // 通过代理对象调用请求}
}
```

代理模式与装饰器模式的区别:实现方式类似,但目标不同:
代理:专注于调用对象的控制。
装饰器:专注于功能扩展。

action test 001

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/989376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

# Residuality Theory批判性分析:架构应该被训练而非设计

关联知识库:# Residuality Theory批判性分析:架构应该被训练而非设计Residuality Theory批判性分析:架构应该被训练而非设计来源: InfoQ - Producing a Better Software Architecture with Residuality Theory 演讲…

# Python 3.14去GIL革命:性能飞跃25%与Python之父的冷静警告

关联知识库:# Python 3.14去GIL革命:性能飞跃25%与Python之父的冷静警告没有。Yeah嗯。嗯# Python 3.14去GIL革命:性能飞跃25%与Python之父的冷静警告核心要点Python 3.14正式提供可选的无GIL(全局解释器锁)支持…

# MVP架构选型指南:停止过度设计,从简单开始

关联知识库:# MVP架构选型指南:停止过度设计,从简单开始MVP架构选型指南:停止过度设计,从简单开始核心观点:大多数 MVP 失败并不是因为无法扩展,而是因为没有人在乎。过度建构堆疊只会导致倦怠和无休止的延遲。…

UV Python包管理器:解释器与虚拟环境工程实践指南【from deepseek】

关联知识库:UV Python包管理器:解释器与虚拟环境工程实践指南【from deepseek】UV Python包管理器:解释器与虚拟环境工程实践指南 1. 核心概念解析 UV的设计哲学 UV采用一体化设计,将包管理、虚拟环境管理和Python…

# 软件危机与复杂性:工程思维的诞生背景

关联知识库:# 软件危机与复杂性:工程思维的诞生背景软件危机与复杂性:工程思维的诞生背景 核心要点速查 ⚡ 软件危机的核心故事线 两次软件危机 → 工程思维诞生 → 解决日益增长的需求和复杂性 第一次软件危机(1…

C++学习备忘:深度解构 C++ 智能指针

出处:https://mp.weixin.qq.com/s/shZyS2WhEfTSgB5_DmgGWw 2025年12月5日 21:41 湖南 在 C 和 C++ 的世界里,指针几乎无处不在,今天我们拆解原生指针的坑,以及智能指针如何帮我们 “躺平” 管理内存,把底层逻辑摸…

线性回归、多层感知机(MLP)与CNN的区别与联系:通俗解析(MindSpore视角)

线性回归、多层感知机(MLP)与CNN的区别与联系:通俗解析(MindSpore视角) 上一篇教程我们用线性回归入门了深度学习,现在聚焦三个核心模型——线性回归、多层感知机(MLP)、卷积神经网络(CNN),用“人话+实例”…

uv —— Rust编写的极速Python包管理工具与镜像源配置指南

关联知识库:uv —— Rust编写的极速Python包管理工具与镜像源配置指南uv —— Rust编写的极速Python包管理工具与镜像源配置指南官方文档:https://docs.astral.sh/uv/ 原文来源:https://www.cnblogs.com/Flat-White…

2025年12月武汉猎头,北京猎头,广州猎头最新榜:综合实力与售后保障深度测评

引言在当今竞争激烈的商业环境中,猎头服务对于企业获取高端人才、提升核心竞争力起着至关重要的作用。为了给企业提供更专业、客观的猎头公司选择参考,我们依据国内相关行业协会的权威测评数据以及专业的白皮书内容,…

2025年12月十大猎头,深圳猎头,杭州猎头盘点:专业能力与行业资源双优之选

引言在当今竞争激烈的商业环境中,企业对于高端人才的需求愈发迫切,猎头服务作为连接企业与高端人才的桥梁,其重要性日益凸显。为了帮助企业更精准地选择优质的猎头公司,我们参考了国内相关行业协会的测评权威数据以…

信息处理检查清单 —— FOLO信息处理工作流构建

关联知识库:信息处理检查清单 —— FOLO信息处理工作流构建恩# 一,反本能的心理建设 为什么我们难以舍弃低价值信息?错失恐惧(FOMO):担心“万一以后用得上呢?”这种心态让我们把潜在价值误当作实际价值情感附着…

# Python开发事实规范:从虚拟环境到工程实践的标准清单

关联知识库:# Python开发事实规范:从虚拟环境到工程实践的标准清单Python开发事实规范:从虚拟环境到工程实践的标准清单文档定位:总结Python开发中已形成事实规范的常识和最佳实践,帮助开发者建立标准化的开发流…

[Python/依赖管理] Python 包与环境管理工具: UV

0 序学习一款新的Python依赖包管理与环境管理工具: UV。"最近几个月,我注意到一个现象:看到的新开源项目里,越来越多开始在README里写uv pip install而不是pip install。"2025年,Python包管理工具已经由…

# Assemble 知识库导航

📚 Assemble 知识库导航本知识库同步到博客,本文档作为博客首页置顶导航本文档为知识库内容导航,下方链接为各主题分类下的精选文章概括,涵盖技术报告、AI编程实践、学术论文、行业观察等核心内容,便于快速定位和…

# Assemble 知识库导航

📚 Assemble 知识库导航本知识库同步到博客,本文档作为博客首页置顶导航本文档为知识库内容导航,下方链接为各主题分类下的精选文章概括,涵盖技术报告、AI编程实践、学术论文、行业观察等核心内容,便于快速定位和…

# 创业公司技术开发失败案例:从技术选型到公司倒闭的血泪教训

关联知识库:# 创业公司技术开发失败案例:从技术选型到公司倒闭的血泪教训创业公司技术开发失败案例:从技术选型到公司倒闭的血泪教训案例背景:一位开发者在2022年6月加入了一家小型创业公司,老板不懂技术也不懂管…

# 结构化拖延批判性分析:John Perry案例

关联知识库:# 结构化拖延批判性分析:John Perry案例结构化拖延批判性分析:John Perry案例 核心观点梳理结构化拖延将“逃避更重要任务”的冲动转化为完成次优任务的驱动力,强调通过任务排序制造“看似紧急”的替代…

利用desmos动态展示最大似然概率

最近碰到最大似然概率的问题,题目一变就出错,痛心!深感没有搞清楚这个求解的意义,有必要搞清楚最大似然值和概率是什么。 传统概率视角:给定参数θ,数据X出现的可能性 \(P(X∣θ)\) 统计推断视角:我已经看到了数…

# 程序员副业陷阱深度解析:万字泣血总结与回归主业之路

关联知识库:# 程序员副业陷阱深度解析:万字泣血总结与回归主业之路程序员副业陷阱深度解析:万字泣血总结与回归主业之路 文章概览 原文标题:《万字泣血解析割韭菜内情,程序员别老想着做副业》 作者:程序员济癫(…

# RAG讣告批判性阅读报告:Agent Search是革命还是过度乐观?

关联知识库:# RAG讣告批判性阅读报告:Agent Search是革命还是过度乐观?RAG讣告批判性阅读报告:Agent Search是革命还是过度乐观?原文:The RAG Obituary: Killed by Agents, Buried by Context Windows 作者:Ni…