在软件设计领域,有许多重要的设计原则,以下为你介绍常见的设计原则及其名称和缩写:
SRP - 单一职责原则(Single Responsibility Principle)
- 定义:一个类应该有且仅有一个引起它变化的原因,也就是说一个类只负责一项职责。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。
- 示例:在一个用户管理系统中,一个类专门负责用户信息的存储,另一个类负责用户信息的验证,这样当存储方式改变或者验证规则改变时,不会相互影响。
OCP - 开闭原则(Open Closed Principle)
- 定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即可以在不必修改源代码的情况下改变这个模块的行为。
- 示例:在一个图形绘制系统中,定义一个抽象的图形基类,各种具体的图形类(如圆形、矩形等)继承自这个基类。当需要添加新的图形类型时,只需要创建一个新的子类,而不需要修改现有的代码。
LSP - 里氏替换原则(Liskov Substitution Principle)
- 定义:所有引用基类的地方必须能透明地使用其子类的对象。也就是说,子类可以扩展父类的功能,但不能改变父类原有的功能。
- 示例:在一个动物类及其子类(如猫、狗)的系统中,任何使用动物类的地方,都可以用猫或狗的对象来替代,而不会影响系统的正确性。
ISP - 接口隔离原则(Interface Segregation Principle)
- 定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。将一个庞大的接口拆分成多个小的、特定的接口,让不同的类实现不同的接口。
- 示例:在一个系统中,有一个 “动物” 接口,包含 “飞行”“游泳”“奔跑” 等方法。但不是所有动物都会这些技能,因此可以将其拆分成 “飞行接口”“游泳接口”“奔跑接口”,让不同的动物类根据自身能力实现相应的接口。
DIP - 依赖倒置原则(Dependency Inversion Principle)
- 定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。即要针对接口编程,而不是针对实现编程。
- 示例:在一个电商系统中,订单服务模块(高层模块)不应该直接依赖具体的数据库操作类(低层模块),而是依赖一个抽象的数据库操作接口,具体的数据库操作类实现这个接口。
CCP - 共同封闭原则(Common Closure Principle)
- 定义:包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。
- 示例:在一个电商系统中,与商品管理相关的类可以放在一个包中,当商品管理的业务规则发生变化时,只影响这个包中的类,而不影响其他与订单管理、用户管理等相关的包。
CRP - 共同重用原则(Common Reuse Principle)
- 定义:一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。也就是说,包中的类之间应该有紧密的联系,它们共同完成一个特定的功能。
- 示例:在一个图形处理库中,与图形绘制算法相关的类可以放在一个包中,当需要使用其中一个绘制算法类时,可能也需要使用该包中的其他相关类来完成整个图形绘制的功能。
=========================================================================
合成 / 聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
- 定义:尽量使用合成 / 聚合,而不是使用继承来达到复用的目的。合成和聚合是关联关系的两种特殊情况,合成表示一种强的 “拥有” 关系,部分和整体的生命周期一致;聚合表示一种弱的 “拥有” 关系,部分可以脱离整体而存在。通过合成 / 聚合复用,可以使系统更加灵活,降低类与类之间的耦合度。
- 示例:在一个汽车系统中,汽车和发动机之间可以是合成关系(发动机是汽车不可分割的一部分),汽车和轮胎之间可以是聚合关系(轮胎可以独立生产和更换)。当需要复用发动机或轮胎的功能时,采用合成 / 聚合的方式,而不是让汽车类继承发动机类或轮胎类。
迪米特法则(Law of Demeter,LoD),也称为最少知识原则
- 定义:一个对象应该对其他对象有最少的了解。也就是说,一个类应该只和它的直接朋友通信,而避免和陌生的类直接通信。直接朋友是指和该类有耦合关系的类,如成员变量、方法参数、方法返回值中的类。
- 示例:在一个公司管理系统中,员工类只需要和其直接上级类(如部门经理类)进行交互,而不需要直接和其他部门的员工类进行交互。如果需要获取其他部门的信息,可以通过上级类进行间接沟通。
好莱坞原则(Hollywood Principle)
- 定义:“Don't call us, we'll call you”(别调用我们,我们会调用你)。在软件设计中,这意味着高层组件控制如何以及何时调用低层组件,低层组件只负责实现具体的功能,而不主动调用高层组件。这种原则常用于框架设计中,框架提供了一个整体的控制流程,开发者编写的代码作为低层组件,在框架需要的时候被调用。
- 示例:在一个 Web 开发框架中,框架负责处理请求的接收、路由等流程,开发者编写的控制器类和业务逻辑类作为低层组件,在框架需要执行具体业务时被调用。
无环依赖原则(Acyclic Dependencies Principle,ADP)
- 定义:在包的依赖关系中,不应该存在循环依赖。即如果包 A 依赖包 B,包 B 依赖包 C,那么包 C 不应该再依赖包 A。循环依赖会导致系统的可维护性和可扩展性变差,因为一个包的修改可能会影响到多个相关的包。
- 示例:在一个大型的软件项目中,将不同的功能模块划分成不同的包。如果存在包 A、包 B 和包 C,包 A 调用包 B 中的类,包 B 调用包 C 中的类,那么包 C 就不应该调用包 A 中的类,以避免形成循环依赖。