开放-封闭原则(Open Closed Principle)

🚏 导论 开放-封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。 对于拓展是开放的(Open for extension),对于更改是封闭的(Closed for modiication) 我们在做任何系统的时候都不要指望系统一开始时需求确定,就再也不会变化,这是不现实也不科学的想法,而既然需求是一定会变化的,那么如何在面对需求的变化时,设计的软件可以相对容易修改,不至于说,新需求一来,就要把整个程序推到重来。怎样的设计才能让软件在需求变化时,可以相对容易的修改呢?这就是开放-封闭原则要解决的问题。 具体来说,在设计的时候,时刻要考虑,尽量让这个类足够好,写好了就不要去修改了,如果新需求来了,增加一些类,原来的代码能不动则不动。当然,绝对的对修改封闭是不可能的。无论模块是多么的“封闭”,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。若猜测失败,要及时的去调整。面对新需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。 开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。 🎬 场景 场景一:🏢 公司管理 现要作为老板,给公司制定考勤制度,规定九点上班,不允许迟到。但是有公司骨干,老是迟到。他们也有实际的难处,比如有些人家离公司太远,有些人每天上午要送小孩子上学。需要对他们特殊处理,但不能违反公司的规定。其实迟到不是问题,最主要的是保证8小时的工作量或是完成业绩目标。于是应该改变管理方式,如弹性上班工作制,早到早下班,晚到晚下班,或者每人每月允许三次迟到,迟到者当天下班补时间等等。对市场销售人员可能就更加以业绩为标准,工作时间不固定了。这其实就是对工作时间或业绩成效的修改关闭,而对时间制度拓展的开放。

January 10, 2025 · 1 min · 16 words · Rex

单一职责原则(Single Responsibility Principle)

🚏 导论 单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因。 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离。 🎬 场景 场景一:📱 手机 现在的手机都有很多功能(除了打电话、发消息):听音乐 、玩游戏、 拍照、摄影等等。但是这里的功能,都是基础功能,实际并没有做的特别专。比如听音乐,手机的音质没有专业的音乐播放器好;拍照,手机的像素没有专业的相机好;玩游戏,手机的操作体验没有专业的游戏机好。所以,手机的功能虽然多,但是都是基础功能,没有做的特别专业。大多时候,一件产品简单一些,职责单一一些,或许是更好的选择。 当然,手机的发展有它的特点,而编程时,我们却是要在类的职责分离上多做思考,做到单一职责,这样代码才是真正的易维护、易扩展、易复用、灵活多样。 场景二:♦️ 俄罗斯方块 俄罗斯方块的实现:俄罗斯方块下落动画的原理是画四个小方块,擦掉,然后再在下一行画四个小方块。不断绘出和擦掉就形成了动画,所以应该要有画和擦方块的动画。然后左右键实现左移和右移,下键实现加速,上键实现旋转,这些其实都应该是函数,当然左右移动需要考虑碰撞的问题,下移需要考虑堆积和消层的问题。 这里大部分都是一些函数,如果将这些函数都放在一个类里,那么这个类就会变得很大,很难维护并且也很难迁移。可以将这些与游戏逻辑相关的函数(下落、旋转、碰撞判断、移动、堆积)提取出来,这些函数和界面如何表示没有特别大的关系,因为所谓方块无非是一个坐标,方块的下落、旋转、碰撞判断、移动、堆积等都是坐标的变化。因此可以将运行界面和游戏逻辑分开,这样就可以更好的维护和迁移。

January 10, 2025 · 1 min · 17 words · Rex

策略模式(Strategy Pattern)

🚏 导论 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。可以用策略模式封装几乎任何类型的规则,只要分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这些变化的可能性。 🧀 前置知识 🚦 结构 UML 类图 classDiagram class Context{ -strategy: Strategy +Context(strategy: Strategy) +contextInterface() } class Strategy{ <<abstract>> +algorithmInterface() } class ConcreteStrategyA{ +algorithmInterface() } class ConcreteStrategyB{ +algorithmInterface() } class ConcreteStrategyC{ +algorithmInterface() } Context o-- Strategy Strategy <|-- ConcreteStrategyA Strategy <|-- ConcreteStrategyB Strategy <|-- ConcreteStrategyC 基本代码 Strategy类,定义所有支持的算法的公共接口。 public abstract class Strategy { /** * 算法方法 */ public abstract void algorithmInterface(); } ConcreteStrategy类,实现具体的算法。 class ConcreteStrategyA extends Strategy { @Override public void algorithmInterface() { System.out.println("算法A实现"); } } class ConcreteStrategyB extends Strategy { @Override public void algorithmInterface() { System.out.println("算法B实现"); } } class ConcreteStrategyC extends Strategy { @Override public void algorithmInterface() { System.out.println("算法C实现"); } } Context, 用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。 ...

January 8, 2025 · 6 min · 1070 words · Rex

抽象工厂模式(Abstract Factory)

🚏 导论 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。当有多个相同的类要实现类似的功能,但是具体的实现细节有所不同,这时候就可以使用抽象工厂模式。 🧀 前置知识 工厂方法模式(Factory Method) 🚦 结构 classDiagram class AbstractFactory{ <<interface>> +createProductA() +createProductB() } class ConcreteFactory1{ +createProductA() +createProductB() } class ConcreteFactory2{ +createProductA() +createProductB() } class AbstractProductA{ <<interface>> } class ProductA1 class ProductA2 class AbstractProductB{ <<interface>> } class ProductB1 class ProductB2 class Client AbstractFactory <|.. ConcreteFactory1 AbstractFactory <|.. ConcreteFactory2 AbstractProductA <|.. ProductA1 AbstractProductA <|.. ProductA2 AbstractProductB <|.. ProductB1 AbstractProductB <|.. ProductB2 Client --> AbstractFactory Client --> AbstractProductA Client --> AbstractProductB AbstractProductA和AbstractProductB是两个抽象产品,之所以抽象,是因为它们有可能有不同的实现,而ProductA1、ProductA2、ProductB1、ProductB2是对两个抽象产品的具体分类实现。 ...

January 7, 2025 · 6 min · 1260 words · Rex

MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework

基本信息 标题: MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework 作者: Sirui Hong、Mingchen Zhuge、Chenglin Wu(通讯作者)等。 作者单位: DeepWisdom、阿卜杜拉国王科技大学、厦门大学、香港中文大学、南京大学、宾夕法尼亚大学、加州大学伯克利分校、瑞士人工智能实验室 期刊/会议: ArXiv 发表年份: 2023 DOI: 2308.00352 开源地址: Github 关键词: MetaGPT, Multi-Agent Collaboration, Standardized Operating Procedures (SOPs), Large Language Models (LLMs), Code Generation 研究背景 (Background) 利用大语言模型的Agent为增强和复制人类的工作流程提供了机会。但是实际应用中,现有系统将复杂问题过度简化。很多人想努力实现有效、连贯和准确的解决问题,尤其是需要协作的任务。而SOP可以有效的分解任务并且协调各个任务,明确的SOPs能够提高任务执行的一致性和准确性,确保其与定义的角色和质量标准相符。 研究问题 (Research Questions) 如何使用应用SOPs与Agent协作开发。 如何优化Agent协作通信能力。 如何提高代码生成的质量。 核心贡献 (Key Contributions) 总结本文的主要贡献点: 引入了MetaGPT,一个基于LLM的多智能体协作元编程框架。 作者在MetaGPT设计中创新性地集成了SOP,减少了LLM的代理之间的无效协作。此外,还引入了一种新颖的执行反馈机制,可以在运行时调试和执行代码,从而提高了代码生成的质量(MBPP上提高了5.4%) 在HumanEval和MBPP达到了SOAT MetaGPT 框架 (MetaGPT Framework) SOP中的Agent(Agents in Stanndard Operating Procedures) 角色的特定职能 解决复杂的任务或问题通常需要具有不同技能和专业知识的智能体协作,每个智能体都针对特定问题提供专门的输出。如在一家软件公司,产品经理的任务是分析业务、软件工程师负责编程开发。因此MetaGPT定义了五个角色:产品经理(Product Manager)、架构师(Architect)、项目经理(Project Manager)、工程师(Engineer)以及QA工程师(QA Engineer)。如下面图1所示: 图1:MetaGPT与真实世界人类团队之间的软件开发SOPs。 在MetaGPT中,对于每个角色制定了Agent的名字(name)、资料(profile)、目标(goal)和约束(constraints)。同时也初始化每个角色的特定的上下文(context)和技能(skill)。例如,产品经理可以使用网络搜索技能,而工程师可以执行代码。如下图2所示。所有Agent遵循ReAct风格。 ...

January 7, 2025 · 2 min · 256 words · Rex