软件设计原则

8/11/2022 计算机基础

软件设计原则是一组用于设计高质量、可维护、可扩展和可重用软件的指导性原则。以下是一些常见的软件设计原则:

  1. 单一职责原则(SRP):一个类应该只有一个职责。
  2. 开放-关闭原则(OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  3. 里氏替换原则(LSP):子类型必须能够替换它们的父类型。
  4. 接口隔离原则(ISP):客户端不应该被强制依赖于它们不使用的接口。
  5. 依赖倒置原则(DIP):高层模块不应该依赖于低层模块,而应该依赖于抽象。
  6. 迪米特法则(LoD):一个对象应该对其他对象有最少的了解。
  7. 合成复用原则(CRP):优先使用对象组合而不是继承来达到复用。

这些原则是软件设计中的基础,它们帮助开发人员设计出高质量、可维护和可扩展的软件系统。

# 单一职责原则

单一职责(Single Responsibility Principle)(SRP)指的是一个类或模块应该只有一个职责。这意味着一个类或模块应该只负责一个功能或任务,这样可以避免代码的复杂性和耦合性。例如,我们可以定义一个名为“UserService”的类来处理用户的注册、登录和个人资料管理等功能。这个类只有一个职责,即管理用户相关的功能。

# 开闭原则

开放-关闭原则(Open-Closed Principle)(OCP)指的是软件实体应该对扩展开放,对修改关闭。这意味着当我们需要修改一个模块或类时,应该通过扩展它来实现,而不是直接修改它。这样可以避免对现有代码的破坏,提高代码的可重用性和可扩展性。例如,我们可以定义一个名为“PaymentService”的类来处理支付功能。当我们需要添加新的支付方式时,可以通过扩展该类来实现,而不是直接修改原有代码。

# 里氏替换原则

里氏替换原则(Liskov Substitution Principle)(LSP)指的是子类型必须能够替换它们的父类型。这意味着当我们使用一个父类的对象时,可以用它的任何子类对象来替换它,而不会影响程序的正确性。例如,我们可以定义一个名为“Animal”的抽象类,它有一个“MakeSound”方法。当我们定义一个“Dog”类时,可以继承“Animal”类,并实现“MakeSound”方法。然后,我们可以使用“Animal”类的对象来调用“Dog”类的“MakeSound”方法,而不会影响程序的正确性。

# 接口隔离原则

接口隔离原则(Interface Segregation Principle)(ISP)指的是客户端不应该被强制依赖于它们不使用的接口。这意味着当一个接口包含了多个方法时,客户端只需要使用其中的一部分方法时,应该将这些方法拆分成多个小的接口。这样可以减少客户端的依赖,提高代码的灵活性和可重用性。例如,我们可以定义一个名为“ILogger”的接口,它有多个方法,如“LogInfo”、“LogError”、“LogWarning”等。当我们需要使用“LogInfo”方法时,可以定义一个新的接口,例如“IInfoLogger”,它只包含“LogInfo”方法。这样,客户端只需要依赖于“IInfoLogger”接口,而不需要依赖于整个“ILogger”接口。

# 依赖倒置原则

依赖倒置原则(Dependency Inversion Principle)(DIP)指的是高层模块不应该依赖于低层模块,而应该依赖于抽象。这意味着模块之间的依赖关系应该通过接口或抽象类来实现,而不是直接依赖于具体的实现类。这样可以减少模块之间的耦合性,提高代码的可扩展性和可维护性。例如,我们可以定义一个名为“DataAccess”的抽象类,它有一个“GetData”方法。当我们定义一个“SqlServerDataAccess”类时,可以继承“DataAccess”类,并实现“GetData”方法。然后,我们可以在高层模块中依赖于“DataAccess”抽象类,而不需要直接依赖于“SqlServerDataAccess”类。

# 迪米特法则

迪米特法则(LoD)指的是一个对象应该对其他对象有最少的了解。这意味着一个对象应该只与其直接的朋友(即与其通信的对象)交互,而不应该与其他对象交互。这样可以减少对象之间的耦合性,提高代码的可维护性和可扩展性。例如,我们可以定义一个名为“Order”的类,它有一个“Customer”属性。当我们需要获取客户的姓名时,可以在“Order”类中调用“Customer”类的“GetName”方法,而不需要直接访问“Customer”类的属性。

# 合成复用原则

合成复用原则(CRP)指的是优先使用对象组合而不是继承来达到复用。这意味着当我们需要复用代码时,应该通过组合现有的对象来实现,而不是通过继承现有的类来实现。这样可以减少代码的耦合性,提高代码的可重用性和可维护性。例如,我们可以定义一个名为“EmailSender”的类,它有一个“SmtpClient”属性。当我们需要发送邮件时,可以通过“SmtpClient”对象来发送邮件,而不需要在“EmailSender”类中实现邮件发送的具体逻辑

# 高内聚低耦合

高内聚和低耦合是两个面向对象编程中重要的概念,它们是编写可维护、可扩展和可重用的代码的关键。

# 高内聚(High Cohesion)

高内聚指的是在一个类、模块或组件中,其包含的各个方法和属性都是高度相关的,并且彼此之间协同工作以实现某个特定的功能。简而言之,高内聚表示一个类或模块的各个元素之间紧密相关,都为实现同一功能而存在。 一个高内聚的模块或类应该具有以下特点: 其各个元素都围绕着一个明确的目标或任务而存在; 其各个元素之间的耦合度较低,相互独立,可以单独修改或测试; 其各个元素之间的交互较少,因此具有更好的可维护性和可重用性; 其各个元素之间的接口简单明了,易于理解和使用。 高内聚是面向对象编程的基本原则之一,它可以帮助我们编写易于维护、易于理解和可重用的代码。

# 低耦合(Low Coupling)

低耦合指的是在一个类、模块或组件中,其各个元素之间的依赖关系较弱,彼此之间的影响较小。简而言之,低耦合表示一个类或模块的各个元素之间相对独立,修改其中一个元素不会对其他元素造成太大的影响。 一个低耦合的模块或类应该具有以下特点:

  • 其各个元素之间的依赖关系较弱,彼此之间的影响较小;
  • 其各个元素之间的接口简单明了,易于理解和使用;
  • 其各个元素之间的依赖关系可以通过接口或抽象类来定义,从而降低耦合度;
  • 其各个元素之间的依赖关系可以通过依赖注入等技术来解耦。
  • 低耦合是面向对象编程的另一个基本原则,它可以帮助我们编写易于维护、易于扩展和可重用的代码。

总之,高内聚和低耦合是两个相互依存、互相支持的概念。只有同时遵循这两个原则,才能编写出高质量的、易于维护的面向对象代码。