设计模式-常见的设计原则或最佳实践
系列文章目录
文章目录
- 系列文章目录
- 设计模式-常见的设计原则或最佳实践
- Overview
- 1.在设计模式中,有哪些常见的设计原则或最佳实践?
- 2.如何将单一职责原则应用到实际的软件开发中?
- 3.如何识别一个类是否违反了单一职责原则?
- 4.能否提供一些实际的案例,说明这些设计原则是如何帮助解决实际问题的?
- 关于作者
设计模式-常见的设计原则或最佳实践
Overview
1.在设计模式中,有哪些常见的设计原则或最佳实践?
在设计模式中,有哪些常见的设计原则或最佳实践?
What are the common design principles or best practices in design patterns?
在设计模式中,有一些核心的设计原则和最佳实践,它们帮助开发者创建灵活、可维护和可扩展的软件系统。以下是一些常见的设计原则:
-
单一职责原则(Single Responsibility Principle, SRP):
每个类应该只有一个引起它变化的原因,即每个类应该只负责一项任务。 -
开放-封闭原则(Open-Closed Principle, OCP):
软件实体应该对扩展开放,对修改关闭。这意味着设计时应当使软件模块易于扩展,但不需要修改现有代码。 -
里氏替换原则(Liskov Substitution Principle, LSP):
子类对象必须能够替换掉它们的父类对象,而不影响程序的行为。 -
接口隔离原则(Interface Segregation Principle, ISP):
客户端不应该依赖于它不使用的接口。应该将大的接口拆分成小的、特定的接口。 -
依赖倒置原则(Dependency Inversion Principle, DIP):
高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。 -
最少知识原则(Law of Demeter, LoD):
一个对象应该对其他对象有最少的了解。只与你的直接朋友通信,不与“朋友的朋友”通信。 -
合成/聚合复用原则(Composite Reuse Principle, CRP):
尽量使用对象的合成/聚合,而不是通过继承来复用代码。 -
迪米特法则(Principle of Least Knowledge, POLK):
一个对象应该对其他对象有最少的了解,只与直接的朋友通信,不与“朋友的朋友”通信。 -
好莱坞原则(Hollywood Principle):
“别调用我们,我们会调用你”。组件应该提供接口供其他组件使用,而不是主动调用其他组件。 -
SOLID原则:
SOLID是上述前五个原则的首字母缩写,它是一个整体的设计原则集合,用于指导面向对象设计。 -
YAGNI(You Aren’t Gonna Need It):
不要为未来可能的需求添加代码,只实现当前需要的功能。 -
KISS(Keep It Simple, Stupid):
保持设计简单,避免不必要的复杂性。 -
DRY(Don’t Repeat Yourself):
避免代码重复。重复的代码会导致维护困难。 -
LOD(Learning Opportunities Daily):
每天都是学习的机会,鼓励开发者不断学习和改进。 -
WET(Write Everything Twice):
在某些情况下,为了保持代码的清晰和简单,重复编写代码可能是可接受的。
这些原则和最佳实践不是一成不变的规则,而是指导软件开发过程中的思考和决策的工具。在实际应用中,开发者需要根据具体情况灵活运用这些原则。
2.如何将单一职责原则应用到实际的软件开发中?
单一职责原则(Single Responsibility Principle, SRP)是面向对象设计原则之一,它指出一个类应该只有一个引起它变化的原因。在实际的软件开发中,应用单一职责原则可以提高代码的可维护性、可读性和可测试性。以下是一些将单一职责原则应用到实际软件开发中的策略:
-
明确类的功能:
在设计类时,首先明确这个类应该承担的功能。如果一个类承担了多个功能,考虑将其拆分成多个类。 -
避免“万能”类:
避免创建一个类来处理所有事情。例如,一个类不应该同时负责数据访问、业务逻辑和用户界面。 -
使用职责分离:
将不同的职责分离到不同的类中。例如,如果一个类既处理用户输入也处理数据存储,应该将其拆分为一个输入处理类和一个数据访问类。 -
抽象和封装:
通过抽象和封装来隐藏类的内部实现细节,只暴露与类职责相关的接口。 -
接口和抽象类:
使用接口和抽象类来定义类应该实现的行为,而不是具体的实现细节。 -
服务定位器模式:
使用服务定位器模式来解耦类之间的依赖关系,使得类只关注自己的职责。 -
依赖注入:
通过依赖注入(Dependency Injection)来提供类需要的外部依赖,而不是让类自己创建或查找这些依赖。 -
模块化:
将应用程序分解为多个模块,每个模块只负责一部分功能。 -
持续重构:
在开发过程中,持续地重构代码,以确保每个类都只承担单一职责。 -
编写单元测试:
编写单元测试来验证类的职责。如果一个类有多个职责,编写测试可能会变得复杂。 -
避免条件语句:
如果一个类中包含大量的条件语句(如if-else或switch-case),这可能是该类承担了多个职责的信号。 -
使用职责链模式:
如果存在多个对象处理请求,可以使用职责链模式来确保每个对象只处理它负责的请求部分。 -
领域驱动设计(DDD):
使用领域驱动设计来定义领域模型,确保每个实体或服务都只处理与其领域相关的职责。
通过将单一职责原则应用到软件开发中,可以创建出更加模块化、灵活和易于维护的系统。然而,也要注意不要过度分解类,这可能会导致系统过于复杂。正确的平衡是关键。
3.如何识别一个类是否违反了单一职责原则?
识别一个类是否违反了单一职责原则通常可以通过以下几个步骤和迹象来判断:
-
检查类的方法数量:
如果一个类有过多的方法,这可能意味着它承担了多个职责。虽然这不是绝对的标准,但可以作为一个初步的警示。 -
分析方法的多样性:
查看类中的方法是否服务于不同的目的。如果方法之间没有明显的联系,或者它们处理的问题领域不同,这可能是违反单一职责原则的迹象。 -
检查类的属性:
如果一个类包含了多种类型的属性,这些属性服务于不同的功能,这可能表明类承担了多个职责。 -
评估条件语句:
如果一个类中包含大量的条件语句(如if-else或switch-case),并且这些条件语句处理的是类的不同功能,这可能是违反单一职责原则的信号。 -
观察类的变化原因:
如果发现类需要因为多种不同的原因而改变,这可能意味着它承担了多个职责。例如,如果一个类既处理用户界面也处理业务逻辑,那么用户界面的变化和业务逻辑的变化都会导致这个类的变化。 -
检查类是否参与多个业务流程:
如果一个类在多个业务流程中扮演不同的角色,这可能意味着它承担了多个职责。 -
评估类的命名:
如果类名不够具体或者包含了多个名词,这可能表明它承担了多个职责。一个好的类名应该清晰地反映出它的职责。 -
检查类是否依赖于多个外部接口:
如果一个类依赖于多个不同的外部接口,并且这些接口服务于不同的功能,这可能是违反单一职责原则的迹象。 -
考虑类的可测试性:
如果发现很难为类编写单元测试,或者需要模拟多个不同的依赖来测试类的不同部分,这可能意味着类承担了多个职责。 -
使用代码度量工具:
可以使用代码度量工具来分析类的复杂度,如圈复杂度、方法数、类内聚性等,这些度量可以帮助识别可能违反单一职责原则的类。 -
团队讨论和代码审查:
通过团队讨论和代码审查,可以发现类是否承担了过多的职责,以及是否有更好的设计选择。
识别违反单一职责原则的类是一个持续的过程,需要开发者保持对代码的敏感度和对设计原则的理解。通过重构和优化,可以逐步改善代码结构,使其更加符合单一职责原则。
4.能否提供一些实际的案例,说明这些设计原则是如何帮助解决实际问题的?
设计原则在软件开发中扮演着至关重要的角色,它们帮助开发者创建出高质量、易于维护和扩展的软件系统。以下是一些实际案例,展示了这些设计原则是如何帮助解决实际问题的:
-
单一职责原则(SRP):
- 例如,在电商平台中,订单类(
Order
)可能同时负责处理订单逻辑、计算总价、打印订单信息以及保存订单到数据库。遵循单一职责原则,这些功能可以被分离到OrderCalculator
、OrderPrinter
和OrderRepository
等不同的类中,每个类只处理一项任务 。
- 例如,在电商平台中,订单类(
-
开闭原则(OCP):
- 在支付系统中,可能需要支持多种支付方式,如信用卡、PayPal、微信支付等。通过使用开闭原则,系统可以在不修改现有代码的情况下,通过添加新的支付方式类来扩展功能,这些类都实现同一个支付接口 。
-
里氏替换原则(LSP):
- 在图形界面编程中,基础控件类如
Button
可能设计为可拖拽。如果RadioButton
继承自Button
,但它不需要拖拽功能,那么RadioButton
不应该重写Button
的拖拽方法,以保证继承体系的稳定性 。
- 在图形界面编程中,基础控件类如
-
接口隔离原则(ISP):
- 考虑一个内容管理系统,如果有一个庞大的接口
ContentEditor
,它包含了编辑文本、图片、视频等所有功能。根据接口隔离原则,这些功能可以被分离到TextEditor
、ImageEditor
和VideoEditor
等更小的接口中,使得实现类只需要依赖它们实际使用的方法 。
- 考虑一个内容管理系统,如果有一个庞大的接口
-
依赖倒置原则(DIP):
- 在构建一个应用程序时,如果高层策略类直接依赖于低层的实现类,这将导致代码难以维护和扩展。依赖倒置原则提倡高层模块应该依赖于抽象,这样可以通过抽象层来注入具体的实现,从而降低模块间的耦合度 。
-
合成/聚合复用原则(CARP):
- 在设计一个企业资源规划(ERP)系统时,可以使用合成或聚合来组合不同的业务组件,如订单处理、库存管理和客户关系管理等。这种设计允许系统灵活地添加或替换组件,而不需要对整个系统进行大规模重构 。
-
尼尔森十大设计原则:
- 例如,腾讯视频通过互动组件和视频进度条的结合,提升了用户参与感和个性化体验 。美团App通过设计心理学和实时活动组件,增强了用户的操控感并缓解了等待焦虑 。
-
UI设计原则:
- 对齐原则确保界面元素有序排列,提升美观性 。格式塔原理中的亲密性原则帮助设计师通过元素的接近程度来创建视觉上的整体感 。
-
模块化设计:
- 通过将软件系统划分为独立的模块,每个模块有明确的接口和功能定义,可以降低复杂性并提高可维护性 。
-
健壮性设计:
- 例如,当软件遇到错误输入或操作时,通过异常处理机制能够保持稳定运行,并给出有用的错误提示 。
通过这些案例,我们可以看到设计原则在实际软件开发中的应用,它们帮助开发者构建出更加健壮、灵活和用户友好的软件系统。
关于作者
- 微信公众号:WeSiGJ
- GitHub:https://github.com/wesigj/cplusplusboys
- CSDN:https://blog.csdn.net/wesigj
- 微博:
- -版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。