Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】

Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】

目录

Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】

一、简单介绍

二、 Unity 设计模式

1、Unity 开发中使用设计模式的特点

2、Unity 中常用的设计模式

3、Unity 开发中使用设计模式的优势

4、Unity 和其他环境使用设计模式的区别总结

三、什么是软件框架,软件框架和设计模式的区别

软件框架和设计模式的区别:

四、开发设计中为什么要使用设计模式

1. 解决常见问题,提升开发效率

2. 促进代码的可维护性

3. 提高代码的可扩展性

4. 增强代码的可复用性

5. 促进团队协作,改善沟通

6. 降低系统的耦合性

7. 应对变化,提高系统的灵活性

8. 避免代码重复

五、设计模式 什么时候使用,怎么使用合适

1. 何时使用设计模式

1.1 当代码重复时

1.2 当系统需要扩展时

1.3 当类和对象的依赖关系过于复杂时

1.4 当需要应对变化时

1.5 当设计不符合SOLID原则时

2. 如何合适地使用设计模式

2.1 识别需求

2.2 避免过度设计

2.3 遵循简单优先原则

2.4 保持灵活性

2.5 组合使用设计模式

2.6 关注可测试性

2.7 学习经典案例

3. 常见设计模式的使用场景

3.1 单例模式(Singleton)

3.2 工厂方法模式(Factory Method)

3.3 观察者模式(Observer)

3.4 策略模式(Strategy)

3.5 装饰者模式(Decorator)

六、23 种设计模式

1、创建型模式(5种)

2、结构型模式(7种)

3、行为型模式(11种)


一、简单介绍

设计模式 是指在软件开发中为解决常见问题而总结出的一套 可复用的解决方案。这些模式是经过长期实践证明有效的 编程经验总结,并可以在不同的项目中复用。设计模式并不是代码片段,而是对常见问题的 抽象解决方案,它提供了代码结构和模块间交互的一种设计思路,帮助开发者解决特定的设计问题。

设计模式的特点:

  1. 通用性:设计模式针对的是软件开发中常见的设计问题,适用于各种软件工程项目。
  2. 可复用性:设计模式可以在不同项目和环境下被重复使用,提高代码的可维护性和扩展性。
  3. 可扩展性:设计模式有助于让代码结构更加灵活,易于扩展和修改。
  4. 模块化:通过设计模式,可以减少代码的耦合性,增强模块间的独立性。
  5. 提高沟通效率:设计模式为开发者提供了一种通用的设计语言,使得团队成员能够快速理解并讨论设计方案。

二、 Unity 设计模式

Unity 开发中使用设计模式 和在其他环境或平台上使用设计模式的核心原理是相同的。设计模式是软件设计中的通用解决方案,用于解决特定的设计问题,无论在哪个开发环境中,其本质都不变。然而,在 Unity 中使用设计模式与在其他开发平台上的应用有一些独特的差异和需要注意的地方,主要与 Unity 的游戏架构组件化设计相关。

1、Unity 开发中使用设计模式的特点

  1. 组件化架构和游戏对象

    • Unity 的核心设计是基于 GameObject-Component 体系,开发者通过将各种组件附加到游戏对象上来定义游戏逻辑。这种架构天然支持将代码功能分解成多个独立的模块,这和许多设计模式的目标非常一致,尤其是单一职责松耦合原则。
    • 例如,在传统的面向对象编程中,继承是常见的组织代码的方式,而在 Unity 中,组合(Composition)更为普遍,开发者可以通过将不同的组件组合到一个游戏对象上,创建丰富的行为。这和某些设计模式(如策略模式)的思想相近,策略模式鼓励通过组合不同策略来改变对象行为,而不是通过继承。
  2. Unity 的生命周期与 MonoBehaviour

    • MonoBehaviour 是 Unity 中的基础脚本类,许多脚本类通过继承它来实现游戏逻辑。MonoBehaviour 提供了一组生命周期方法,如 Start()Update()OnTriggerEnter() 等,用来管理脚本的执行顺序。
    • 在 Unity 中使用设计模式时,必须考虑 Unity 的这种生命周期管理。例如,单例模式在其他环境下可能涉及懒加载或复杂的初始化逻辑,而在 Unity 中,单例对象通常会与 DontDestroyOnLoad 方法结合,确保它在场景切换时不被销毁。
  3. 游戏开发的实时性

    • 实时性是游戏开发中的关键因素,Unity 开发中往往需要处理大量实时的输入输出、物理运算、渲染等。在这种环境下,设计模式的使用需要考虑到性能开销。例如,在使用观察者模式时,观察者的数量和频率可能会影响游戏的帧率,所以需要特别小心管理订阅与通知的机制。
  4. 脚本与引擎的紧密结合

    • 在 Unity 中,脚本和引擎的底层功能紧密结合,例如物理引擎、渲染系统、动画系统等。因此,设计模式在使用时通常需要与 Unity 提供的 API 协同工作。
    • 例如,在实现工厂方法模式时,开发者可能需要通过 Unity 的 Instantiate() 方法动态创建游戏对象,而不是直接使用面向对象编程中的 new 操作符。这意味着在 Unity 中使用某些设计模式时,需要借助 Unity 的特定工具和功能。

2、Unity 中常用的设计模式

  1. 单例模式 (Singleton)

    • 应用场景:用于全局管理器类,如 GameManagerAudioManager,确保全局状态在整个游戏生命周期中唯一且可访问。
    • Unity 特点:通常结合 DontDestroyOnLoad() 方法来保证在场景切换时,单例对象不会被销毁。
  2. 工厂方法模式 (Factory Method)

    • 应用场景:用于动态生成游戏对象,如敌人、道具等。通过工厂方法,可以根据游戏逻辑在不同时间点生成不同类型的对象。
    • Unity 特点:通常结合 Instantiate() 方法来生成对象的实例,并从资源中加载预制件(Prefab)。
  3. 观察者模式 (Observer)

    • 应用场景:用于处理事件机制,如 UI 按钮点击、游戏中角色生命值变化、AI 事件等。
    • Unity 特点:可以使用 Unity 的事件系统(如 UnityEvent),或自行管理观察者列表。
  4. 状态模式 (State)

    • 应用场景:用于控制对象的状态切换,尤其是在角色动画、AI 行为树等场景中非常有用。
    • Unity 特点:可以结合 Unity 的 Animator 状态机,管理复杂的状态切换。
  5. 策略模式 (Strategy)

    • 应用场景:用于动态改变对象行为,如不同武器或攻击方式、不同移动方式等。
    • Unity 特点:可以通过将不同的行为封装为独立的脚本组件,并根据需要动态添加或移除组件,来实现灵活的行为切换。
  6. 命令模式 (Command)

    • 应用场景:用于实现撤销操作、输入控制器、行为记录等。
    • Unity 特点:可以结合 Unity 的输入系统来实现一系列命令的执行和撤销操作。

3、Unity 开发中使用设计模式的优势

  1. 提高代码复用性:设计模式有助于将复杂的功能拆解为可复用的组件。例如,通过工厂模式和预制件,开发者可以动态生成各种对象,而不必重复编写对象初始化代码。

  2. 增强代码的可维护性和扩展性:例如,通过状态模式管理角色状态,使得后期修改或添加新的状态变得更加容易,而不需要重写或修改大量代码。

  3. 符合 Unity 组件化设计:Unity 强调通过组件组合实现复杂功能,这与很多设计模式(如策略模式、装饰模式)的思路不谋而合。通过使用这些设计模式,开发者能够更加灵活地组织代码,使其更符合 Unity 的框架结构。

  4. 减少耦合性:设计模式如观察者模式可以减少不同模块之间的耦合,使代码结构更为松散,方便以后扩展或维护。

4、Unity 和其他环境使用设计模式的区别总结

特性Unity 中使用设计模式其他开发平台中使用设计模式
组件化架构基于 GameObject 和 Component 体系,倾向于组合而非继承传统面向对象编程中常使用继承,较少采用组合
生命周期管理受 MonoBehaviour 生命周期的影响,设计模式可能需要适应这种结构自由管理对象的创建与销毁,生命周期不依赖于引擎
实时性需求游戏开发中需要高效管理设计模式,避免性能问题其他系统中,实时性要求相对较低,设计模式对性能影响较小
引擎和 API 交互需要结合 Unity API,如 Instantiate()、Animator 等大多数情况下依赖于标准库和 API,自由度较高
场景切换和数据持久化设计模式需要考虑跨场景的数据管理,如使用 DontDestroyOnLoad()常规应用中,数据管理不需要考虑场景切换,通常依赖数据库等持久化

总之,Unity 中的设计模式应用与传统开发环境有一些区别,主要体现在 Unity 的组件化架构生命周期管理上。开发者需要根据 Unity 的独特特性来调整设计模式的实现方式,以便更好地与 Unity 引擎协同工作。通过合理使用设计模式,开发者可以创建更具扩展性、可维护性和复用性的代码,同时提高开发效率和代码质量。

三、什么是软件框架,软件框架和设计模式的区别

软件框架 是一个 可复用的代码结构或库,它为软件开发提供了一个 基本的骨架和通用功能,开发人员可以在此基础上进行扩展和定制,以满足特定应用的需求。框架通常提供一组标准化的接口、类和工具,帮助开发者快速开发应用程序,而不需要从零开始编写底层代码。

软件框架的特点:

  1. 可复用性:框架提供了大量可复用的组件和模块,使开发者无需重复开发常见功能。
  2. 约定优于配置:框架通常包含默认的约定和最佳实践,开发者只需遵循框架的约定,便可避免大量的配置工作。
  3. 控制反转(Inversion of Control, IoC):在框架中,控制权通常从开发者转移到框架。框架会自动管理应用程序的流程和生命周期,开发者只需在特定点扩展代码。
  4. 简化开发流程:通过提供常见功能的实现,如数据库交互、UI 渲染、网络通信等,框架简化了开发流程,提高了开发效率。
  5. 扩展性:开发者可以在框架的基础上扩展功能,框架通常允许定制和扩展特定模块。

设计模式:

设计模式是 通用的、可复用的解决方案,用于解决软件设计中的特定问题。设计模式是一种高层次的设计思路,是对编程中常见问题的总结和抽象。

软件框架和设计模式的区别

特性Unity 中使用设计模式其他开发平台中使用设计模式
组件化架构基于 GameObject 和 Component 体系,倾向于组合而非继承传统面向对象编程中常使用继承,较少采用组合
生命周期管理受 MonoBehaviour 生命周期的影响,设计模式可能需要适应这种结构自由管理对象的创建与销毁,生命周期不依赖于引擎
实时性需求游戏开发中需要高效管理设计模式,避免性能问题其他系统中,实时性要求相对较低,设计模式对性能影响较小
引擎和 API 交互需要结合 Unity API,如 Instantiate()、Animator 等大多数情况下依赖于标准库和 API,自由度较高
场景切换和数据持久化设计模式需要考虑跨场景的数据管理,如使用 DontDestroyOnLoad()常规应用中,数据管理不需要考虑场景切换,通常依赖数据库等持久化

总之,两者之间的主要区别在于,框架是一种可以直接使用的工具和代码库,而设计模式则是对软件设计的经验总结,提供了一种组织代码的模式和思路。

  • 软件框架 是更具 实际性 的工具,它为开发者提供了代码实现和通用功能,可以直接使用,通常用于开发某一类型的应用程序。
  • 设计模式 是一种 理论性的设计方案,用于指导如何设计代码结构,解决开发中反复出现的问题。设计模式强调的是设计原则和结构,不提供直接的代码实现。

四、开发设计中为什么要使用设计模式

在软件开发中使用设计模式的主要目的是为了提高代码的 可维护性可扩展性 复用性。设计模式提供了经过验证的、可重复使用的解决方案,帮助开发人员避免常见的设计问题,简化开发过程。具体来说,使用设计模式有以下几个主要原因:

1. 解决常见问题,提升开发效率

设计模式是经过实践检验的通用解决方案,针对常见的设计挑战提供了标准化的方法。通过应用这些模式,开发人员不必从零开始设计解决方案,可以直接借用已有的模式来解决类似问题,从而提高开发效率。

2. 促进代码的可维护性

设计模式帮助开发人员构建更加清晰的代码结构,减少复杂性,方便后期的维护和修改。例如,使用单例模式可以确保系统中的某个类只有一个实例,避免了全局状态混乱,便于管理。而观察者模式则可以帮助系统模块之间松散耦合,易于扩展和维护。

3. 提高代码的可扩展性

设计模式鼓励使用接口和抽象类来解耦模块,使系统的各个部分独立演化。例如,工厂方法模式抽象工厂模式通过创建对象的接口,将实例化对象的具体类与使用这些对象的代码分离,允许轻松扩展或更改系统功能,而不破坏现有代码。

4. 增强代码的可复用性

设计模式使代码具备更高的复用性。许多设计模式通过封装变化的部分,使得代码可以在不同场景下复用。比如,策略模式将算法和具体实现分离,可以动态替换不同的算法,而无需修改客户端代码,从而增强了代码的复用能力。

5. 促进团队协作,改善沟通

设计模式是一种通用的设计语言,使用设计模式可以促进团队成员之间的沟通。不同的开发者在讨论系统设计时,通过提及具体的设计模式(如代理模式装饰者模式),能够快速理解彼此的设计意图,减少沟通障碍。

6. 降低系统的耦合性

设计模式通过将模块之间的交互松散耦合,降低了系统各部分之间的依赖性。例如,观察者模式可以实现模块之间的松散耦合,使得一个模块的变化不会影响其他模块,从而提高系统的灵活性和可扩展性。

7. 应对变化,提高系统的灵活性

设计模式帮助开发人员构建适应变化的系统。软件开发中,需求经常发生变化,设计模式通过提供灵活的结构,使得系统可以更容易地适应这些变化。例如,状态模式允许对象在状态变化时切换行为,避免了大量的if-else语句。

8. 避免代码重复

设计模式提供了标准的解决方案,可以避免重复实现相同功能的代码。例如,模板方法模式定义了算法的骨架,允许子类重写某些步骤,而无需重复整个算法的实现,减少了代码重复,提高了代码的一致性。

总之,使用设计模式不仅能够解决常见的设计问题,还可以提升代码的可读性、可维护性和扩展性,帮助开发人员创建灵活、易于修改的系统。同时,它们作为一种通用的开发语言,能促进团队协作和沟通,使开发工作更加高效。

五、设计模式 什么时候使用,怎么使用合适

使用设计模式 的关键在于解决特定的软件设计问题,而不只是为使用而使用。选择适当的设计模式可以提高代码的质量和开发效率。要知道什么时候使用和如何合适地使用设计模式,必须基于问题的性质、软件的复杂度、团队协作需求等。以下是一些原则和使用建议:

1. 何时使用设计模式

1.1 当代码重复时

当你发现系统中存在重复代码时,可以考虑使用设计模式来减少重复。例如,如果多个地方都在实现相似的对象创建逻辑,你可以使用工厂方法模式来统一对象的创建逻辑。

1.2 当系统需要扩展时

如果系统在未来可能需要扩展,那么设计模式可以帮助构建灵活的架构。例如,策略模式允许你轻松添加新的算法或操作,而不修改现有代码;装饰者模式允许你动态扩展对象的功能,而不影响其他对象。

1.3 当类和对象的依赖关系过于复杂时

当你发现类之间的依赖关系过于紧密,难以维护或扩展时,设计模式可以帮助解耦。比如,观察者模式可以使类之间松散耦合,避免直接依赖;中介者模式可以集中管理对象间的交互,减少直接的依赖。

1.4 当需要应对变化时

如果你预见到系统某些部分会频繁变化,而其他部分则相对稳定,那么可以使用设计模式来隔离变化。例如,状态模式适用于当对象状态变化时需要改变其行为的场景,避免了硬编码多个if-else语句。

1.5 当设计不符合SOLID原则时

设计模式能帮助你遵循SOLID原则(单一职责、开闭原则、里氏替换、接口分离、依赖倒置)。例如,依赖倒置原则可以通过使用依赖注入抽象工厂模式来实现,减少高层模块对低层模块的依赖。

2. 如何合适地使用设计模式

2.1 识别需求

首先,清楚理解问题或需求。不要盲目使用设计模式,除非它能解决特定的问题。每种设计模式都有其特定的应用场景。例如:

  • 如果你的系统需要支持不同的产品创建过程,使用工厂模式
  • 如果你需要为一个对象动态地添加行为,可以考虑装饰者模式
  • 如果你的对象需要根据不同的状态表现出不同的行为,使用状态模式
2.2 避免过度设计

设计模式的使用应当有针对性。过度使用设计模式可能会使系统复杂化,增加代码的阅读和维护成本。仅在需要时使用设计模式,不要为了炫技或追求模式而引入不必要的复杂性。例如,单例模式虽然简单,但如果过度使用,可能导致全局状态共享,增加调试难度。

2.3 遵循简单优先原则

始终优先选择简单而清晰的设计方案。如果某个问题可以通过简单的继承或组合来解决,那么没有必要引入复杂的设计模式。设计模式是解决复杂问题的工具,但不要让模式增加不必要的复杂性。

2.4 保持灵活性

使用设计模式时要考虑到系统的未来扩展。设计模式应当是灵活的,避免硬编码逻辑。例如,策略模式允许你动态替换算法,而不是写死逻辑,这样可以灵活地适应变化的需求。

2.5 组合使用设计模式

在复杂的系统中,有时需要组合多种设计模式来解决问题。例如,工厂模式可以与单例模式组合使用,确保创建的对象是单例的;或者将观察者模式中介者模式结合使用,管理多个观察者的交互。

2.6 关注可测试性

设计模式还能提升代码的可测试性。通过使用依赖注入工厂方法模式,可以让代码依赖于接口而不是具体实现,从而更容易进行单元测试和替换依赖。

2.7 学习经典案例

学习常见的设计模式应用场景和经典案例,尤其是在已有的框架或库中。例如,Java 中的java.util.Observer接口实现了观察者模式,Spring 框架中广泛使用的依赖注入机制基于依赖倒置原则和工厂模式。

3. 常见设计模式的使用场景

3.1 单例模式(Singleton)
  • 使用场景:确保某个类只有一个实例,例如数据库连接池或配置管理类。
  • 如何使用:控制类的实例化,提供全局访问点。
3.2 工厂方法模式(Factory Method)
  • 使用场景:当需要创建对象但不想显式指定对象的类时。
  • 如何使用:定义一个用于创建对象的接口,将具体的对象创建工作推迟到子类。
3.3 观察者模式(Observer)
  • 使用场景:当一个对象状态发生变化时需要通知其他对象,如事件监听系统。
  • 如何使用:定义一对多的依赖关系,一个对象状态变化时通知所有依赖对象。
3.4 策略模式(Strategy)
  • 使用场景:当有多种算法可以替换且需要动态选择时,例如支付方式选择。
  • 如何使用:定义一组算法,将它们封装在独立的类中,并通过接口进行互换。
3.5 装饰者模式(Decorator)
  • 使用场景:需要动态地给对象增加功能,而不影响其他对象时。
  • 如何使用:用一个装饰对象包裹真实对象,在不改变对象结构的情况下增加新功能。

总之,使用设计模式的关键在于正确理解问题的性质,结合设计模式的应用场景来做出合适的选择。要避免过度设计,保持代码简单,同时确保系统的灵活性和可维护性。掌握常见设计模式及其组合,能够帮助你应对复杂的软件设计问题,提升代码质量。

六、23 种设计模式

1、创建型模式(5种)

  1. 工厂方法模式(Factory Method):定义一个接口用于创建对象,但让子类决定实例化哪一个类。
  2. 抽象工厂模式(Abstract Factory):提供一个创建相关或依赖对象的接口,而不指定具体类。
  3. 单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点。
  4. 建造者模式(Builder):将对象的构建与其表示分离,以便相同的构建过程可以创建不同的对象。
  5. 原型模式(Prototype):通过复制现有的实例来生成新对象,而不是通过实例化类。

2、结构型模式(7种)

  1. 适配器模式(Adapter):将一个类的接口转换为客户希望的另一个接口,使原本不兼容的类可以一起工作。
  2. 桥接模式(Bridge):将抽象部分与它的实现部分分离,以使它们可以独立变化。
  3. 装饰者模式(Decorator):动态地给一个对象添加新的职责,避免了创建子类的需要。
  4. 组合模式(Composite):将对象组合成树形结构以表示部分-整体的层次结构,客户可以同样地对待单个对象和组合对象。
  5. 外观模式(Facade):为子系统中的一组接口提供一个统一的接口,使得子系统更容易使用。
  6. 享元模式(Flyweight):通过共享细粒度的对象来减少内存使用。
  7. 代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。

3、行为型模式(11种)

  1. 模板方法模式(Template Method):在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。
  2. 命令模式(Command):将请求封装为对象,从而可以用不同的请求对客户进行参数化、排队或记录请求日志,以及支持可撤销操作。
  3. 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
  4. 观察者模式(Observer):定义对象间的一对多依赖,当一个对象改变状态时,其依赖者都会得到通知并自动更新。
  5. 中介者模式(Mediator):定义一个对象来封装一系列对象之间的交互,中介者使各对象不需要显式地相互引用,从而使它们之间的耦合松散,且可以独立地改变它们之间的交互。
  6. 备忘录模式(Memento):在不破坏封装性的前提下,捕获对象的内部状态,并在以后恢复该状态。
  7. 解释器模式(Interpreter):为某个语言定义一个语法表示,并定义一个解释器,使用该表示来解释语言中的句子。
  8. 状态模式(State):允许对象在内部状态改变时改变它的行为,看起来对象好像修改了它的类。
  9. 策略模式(Strategy):定义一系列算法,将每一个算法封装起来,并让它们可以互换,策略模式使得算法可以独立于使用它的客户而变化。
  10. 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
  11. 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

在日常应用中,设计模式从来都不是单个设计模式独立使用的。在实际应用中,通常多个设计模式混合使用,你中有我,我中有你。下图完整地描述了设计模式之间的混用关系,希望对大家有所帮助。

七、七大设计原则(SOLID)

设计模式中的设计原则是软件设计的核心思想,旨在帮助开发人员创建更具可维护性可扩展性灵活性的代码结构。这些原则是设计模式的基础,指导我们如何编写高内聚、低耦合的代码。以下是设计模式中常见的设计原则:

1. 单一职责原则 (Single Responsibility Principle, SRP)

  • 定义:一个类只负责一项职责,应该只有一个引起它变化的原因。
  • 解释:每个类都应该有且只有一个功能或行为。如果一个类承担了过多的责任,修改一个功能可能会影响到其他功能,增加维护的复杂性。
  • 实例:假设有一个类既负责文件的保存,又负责文件内容的格式化。这时应将它拆分为两个类:一个负责文件保存,一个负责格式化。

2. 开闭原则 (Open/Closed Principle, OCP)

  • 定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  • 解释:当需求发生变化时,应该通过扩展类的行为来应对新需求,而不是修改已有的代码。这减少了对现有代码的影响,避免引入新 bug。
  • 实例:在处理不同类型的支付时,添加新的支付方式应该通过继承扩展,而不是修改现有的支付处理逻辑。

3. 里氏替换原则 (Liskov Substitution Principle, LSP)

  • 定义:所有引用基类的地方必须能透明地使用其子类对象。
  • 解释:子类应该能够替换其基类,而不影响程序的正确性。换句话说,子类应该完全遵循基类的行为规范,不能违背基类的约定。
  • 实例:如果基类 Animal 有一个方法 makeSound(),而 DogCat 类继承了它,那么无论是 Dog 还是 Cat 对象,都应该能够被用作 Animal 类型,而不影响程序功能。

4. 依赖倒置原则 (Dependency Inversion Principle, DIP)

  • 定义:高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  • 解释:在设计中,应该尽量依赖抽象(接口或抽象类),而不是具体实现。这样可以减少类之间的耦合,使代码更加灵活。
  • 实例:一个高层模块 PaymentService 应该依赖于 IPaymentProcessor 接口,而不是具体的 PaypalProcessor 类。这样可以轻松替换不同的支付处理方式,而不需要修改 PaymentService 的代码。

5. 接口隔离原则 (Interface Segregation Principle, ISP)

  • 定义:客户端不应该依赖于它不需要的接口。
  • 解释:应将大接口拆分为多个小接口,每个接口只包含客户端所需的方法。这样避免客户端实现冗余的接口方法,减少不必要的依赖。
  • 实例:如果一个接口包含了太多职责,比如 IWorker 接口既有 work() 方法又有 eat() 方法,那么不相关的类会被迫实现不需要的方法。应该将 IWorker 接口分为 IWorkableIEatable,分别定义不同职责的接口。

6. 迪米特法则 (Law of Demeter, LoD)

  • 定义:一个对象应该对其他对象有最少的了解。
  • 解释:又称最少知识原则,它强调对象之间的低耦合。一个对象不应该直接操作或依赖于其他类的内部细节,只应该通过其直接依赖的对象进行通信。
  • 实例:假设有一个类 Car,它有一个 Engine 对象。在设计时,Car 应该只通过 Engine 的公共接口与 Engine 交互,而不是深入访问 Engine 内部的子对象。

7. 合成复用原则 (Composition Over Inheritance)

  • 定义:尽量使用组合(对象包含关系)来实现功能,而不是通过继承。
  • 解释:通过组合,将类的功能封装成独立的组件,避免继承带来的层级复杂性和继承耦合问题。组合可以实现更灵活的对象行为扩展,而继承会造成类的高度依赖。
  • 实例:假设你有一个类 Bird,而想创建会游泳的鸟类,应该使用一个 Swimming 组件来添加游泳功能,而不是通过继承多个类来实现(如 SwimmingBird)。
七大设计原则
开闭原则面对需求,对程序的改动是通过增加新代码进行的,而不是改变原来的标题
依赖倒转原则高层模块不应该依赖底层模块,两个都应该依赖与抽象;抽象不应该依赖于细节,细节应该依赖于抽象。所以要针对接口编程,不要针对实现编程。
里氏代换原则由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象
单一职责原则一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类,就一个类而言,应该仅有一个引起它变化的原因
接口隔离原则接口隔离原则是指使用多个专门的接口,而不使用单一的总接口。每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都要干
合成复用原则合成复用原则就是指在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的。简言之:要尽量使用组合/聚合关系,少用继承
迪米特法则一个软件实体应当尽可能少的与其他实体发生相互作用。在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限

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

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

相关文章

如何使用 Rust 框架进行 RESTful API 的开发?

一、RESTful API 的开发 使用 Rust 框架进行 RESTful API 开发,你可以选择多种流行的 Rust Web 框架,如 Actix-web、Rocket、Warp 和 Tide 等。以下是使用这些框架进行 RESTful API 开发的基本步骤和概念: 选择框架:根据项…

Ultimate Screenshot Tool

终极截图工具是资产商店中最好的截图工具! 易于使用,在任何地方都有最多的功能和自定义选项,在所有平台和管道上的游戏和编辑器中轻松捕获、编辑和共享高清屏幕截图。 WebGL演示-文档-Gif组合 轻松截图: -在编辑器和游戏中轻松截取高清屏幕截图! -预览您的所有设备,在所有…

核心复现—计及需求响应的区域综合能源系统双层优化调度策略

目录 一、主要内容: 二、摘要介绍: 三、综合能源系统结构: 四、实际仿真运行结果: 五、代码数据下载: 一、主要内容: 在模型构建部分:建立了一个综合能源系统双层优化调度模型,…

8. 防火墙

8. 防火墙 (1) 防火墙的类型和结构 防火墙的类型和结构可以根据其在网络协议栈中的过滤层次和实现方式进行分类。常见的防火墙类型包括: 包过滤防火墙:工作在网络层(OSI模型的第3层),主要检查IP包头的信息,如源地址、目的地址、端口号等。电路级网关防火墙:工作在会话层…

Rust GUI框架 tauri V2 项目创建

文章目录 Tauri 2.0创建应用文档移动应用开发 Android 前置要求移动应用开发 iOS 前置要求参考资料 Tauri 2.0 Tauri 是一个构建适用于所有主流桌面和移动平台的轻快二进制文件的框架。开发者们可以集成任何用于创建用户界面的可以被编译成 HTML、JavaScript 和 CSS 的前端框架…

2024年9月22日---关于MyBatis框架(1)

一 Mybatis概述 1.1 简介 MyBatis(官网:mybatis – MyBatis 3 | 简介 )是一款优秀的开源的 持久层 框架,用于简化JDBC的开发。是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code&#xff0c…

教你一招:在微信小程序中为用户上传的图片添加时间水印

在微信小程序开发过程中,我们常常需要在图片上添加水印,以保护版权或增加个性化元素。本文将为大家介绍如何在微信小程序中为图片添加时间水印,让你的小程序更具特色。 实现步骤: 1. 创建页面结构 在pages目录下创建一个名为upl…

防火墙详解(一) 网络防火墙简介

原文链接:https://blog.csdn.net/qq_46254436/article/details/105519624 文章目录 定义 与路由器和交换机的区别 发展历史 防火墙安全区域 定义 防火墙主要用于保护一个网络区域免受来自另一个网络区域的网络攻击和网络入侵行为 “防火墙”一词起源于建筑领域&…

苍穹外卖学习日志 -----20天项目从零到完结-----含软件下载,环境配置,框架学习,代码编写,报错处理,测试联调,每日总结,心路历程等等......

年份 2024 基础:Javase Javaweb 已完结 2024 8.25---9.14 20天 Day-01 8.25 今天开始学习已经晚了,网盘下载了一下文件,做了一些开始项目的准备工作。 本来其实打算用notepad来写学习日志的,但是那个传…

FreeRTOS学习——链表list

FreeRTOS学习——链表(列表)list,仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 参考大佬的好文章: freertos内核原理 Day1(链表) FreeRTOS-链表的源码解析 *list_t只能存储指向list_item_t的指针。每个list_item_t都…

【Taro】初识 Taro

笔记来源:编程导航。 概述 Taro 官方文档:https://taro-docs.jd.com/docs/ (跨端开发框架) Taro 官方框架兼容的组件库: taro-ui:https://taro-ui.jd.com/#/ (最推荐,兼容性最好&…

【渗透测试】-vulnhub源码框架漏洞-Os-hackNos-1

vulnhub源码框架漏洞中的CVE-2018-7600-Drupal 7.57 文章目录  前言 1.靶场搭建: 2.信息搜集: 主机探测: 端口扫描: 目录扫描: 3.分析: 4.步骤: 1.下载CVE-2018-7600的exp 2.执行exp: 3.写入木…

电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程

一、前言 电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程 佳易王电玩店计时计费软件,有两款,其中一款可显示倒计时剩余分钟数,另外一款是显示用了多长时间,都可以设置定时语音提醒。 二、显示倒计时软件图文…

【超详细】基于YOLOv8训练无人机视角Visdrone2019数据集

主要内容如下: 1、Visdrone2019数据集介绍 2、下载、制作YOLO格式训练集 3、模型训练及预测 4、Onnxruntime推理 运行环境:Python3.8(要求>3.8),torch1.12.0cu113(要求>1.8)&#xff0c…

策略模式与工厂模式的区别

《策略模式与工厂模式的区别》 策略模式(Strategy Pattern) 和 工厂模式(Factory Pattern) 都是常见的设计模式,虽然它们在设计目标上有一些相似之处,如解耦代码、增强扩展性,但它们的应用场景和…

基于单片机的智能小车的开发与设计

摘要:本文论述了基于 STC89C52 单片机的智能小车的开发与设计过程。该设计采用单片机、电机驱动及光电循迹等技术,保证小车在无人管理状态下,能按照预先设定的线路实现自动循迹功能。在电路结构设计中力求方便,可操作,…

文件操作

文件的由来:在程序中,之前每一个程序都是需要运行然后输入数据,当程序结束时输入的数据也随之消散,为了下一次运行时不再输入数据就有文件的由来,使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据…

软件著作权登记所需要的材料

软件著作权登记所需材料全面解析 在当今数字化时代,软件著作权作为保护软件开发者智力劳动成果的重要法律手段,其登记过程显得尤为重要。 一、软件著作权登记申请表 首先,软件著作权登记需要提交的最基本材料是《软件著作权登记申请表》。这份…

照片写真记录摄影作品记录网站源码

完美适应iPad,平板,手机竖屏不支持lazy,横屏可以,但建议使用平板查看效果, 有服务器直接上传解压使用,环境nginxphp, 没有服务器也没关系,可以直接使用html

前端项目代码开发规范及工具配置

在项目开发中,良好的代码编写规范是项目组成的重要元素。本文将详细介绍在项目开发中如何集成相应的代码规范插件及使用方法。 项目规范及工具 集成 EditorConfig集成 Prettier1. 安装 Prettier2. 创建 Prettier 配置文件3. 配置 .prettierrc4. 使用 Prettier 集成 …