软件设计模式学习(二)面向对象设计原则

面向对象设计原则

面向对象设计原则是学习设计模式的基础,每一种设计模式都符合某一种或多种面向对象设计原则。在软件开发中使用这些原则可以提高软件的可维护性和可复用性,让我们可以设计出更加灵活也更容易扩展的软件设计,实现可维护性复用的目标。

单一职责原则

  • 定义

    一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。

  • 分析

    一个类承担的职责越多,被复用的可能性越小,并且相当于将这些职责耦合在一起。因此需要将这些职责进行分离,实现高内聚、低耦合的指导方针。

开闭原则

  • 定义

    一个软件实体应当对扩展开放,对修改关闭。也就是说在设计一个模块,应当使这个模块可以在不被修改的前提下被扩展。

  • 分析

    在开闭原则的定义中,软件实体可以是一个软件模块、一个由多个类组成的局部结构或一个类。

    软件的需求会随着时间推移发生变化,如果软件设计符合开闭原则,就可以在扩展时无须修改现有代码,保证稳定性与延续性。

    抽象化是满足开闭原则的关键,通过定义一个相对稳定的抽象层,将不同的实现行为在具体实现层中实现。如果需要修改,无须改动抽象层,只需增加新的实体类来实现新的业务功能即可。

里氏代换原则

  • 定义

    里氏代换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。

    说白了就是:在软件中如果能使用其基类对象,那么一定能使用其子类对象。把基类都替换成它的子类,程序不会产生任何错误。但反过来则不成立,如果一个软件实体使用的是一个子类,那么它不一定能使用基类。

  • 分析

    里氏代换原则是实现开闭原则的重要方式之一,在程序中尽量使用基类类型来定义对象,而在运行时再确定其子类类型,用子类对象来替代父类对象。

依赖倒转原则

  • 定义

    高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。即代码要依赖于抽象的类,而不依赖于具体的类,要针对接口编程,不要针对实现编程。

  • 分析

    如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要手段。下面介绍依赖倒转原则中经常提到的两个概念。

    • 类之间的耦合

      在面向对象系统中,两个类之间通常可以发生三种不同的耦合关系(依赖关系)

      1. 零耦合关系:两个类之间没有任何耦合关系
      2. 具体耦合关系:两个具体类之间存在一个类对另一个具体类实例的直接引用
      3. 抽象耦合关系:发生在一个具体类和抽象类之间,也可以发生在两个抽象类之间。依赖倒转原则要求客户端依赖于抽象耦合。
    • 依赖注入

      简单来说,依赖注入就是将一个类的对象传入另一个类,注入时应该注入父类对象,而在程序运行时再通过子类对象来覆盖父类对象。依赖注入有三种方式

      1. 构造注入:通过构造函数注入实例变量
      2. 设值注入:通过Setter方法注入实例变量
      3. 接口注入:通过接口方法注入实例变量

接口隔离原则

  • 定义

    一旦一个接口太大,则需要将它分割成一些更小的接口,使用该接口的客户端仅需知道与之相关的方法即可。

  • 分析

    这里的接口往往有两种不同的含义:

    1. 一种是指一个类型所具有的方法的特征的集合,仅仅是逻辑上的概念,接口的划分将直接带来类型的划分。此时可以把接口理解成角色,一个接口只代表一个角色,每个角色都有它特有的一个接口,此时这个原则叫做角色隔离原则。
    2. 另一种是指接口仅仅提高客户端需要的行为,即所需的方法。接口应该尽量细化,接口中的方法进来少,每个接口只包含一个客户端所需的角色。

合成复用原则

  • 定义

    尽量使用组合对象,而不是继承来达到复用的目的。通俗来说,合成复用原则就是指一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用已有功能的目的。

  • 通过继承来实现复用很简单,子类可以覆盖父类方法,易于扩展。但会破坏系统的封装性,因为继承会将基类的实现细节暴露给子类,这种复用又称为“白箱复用”。

    通过组合/聚合来复用是将一个类的对象作为另一个类的对象的一部分。新对象可以调用已有对象的功能,这种复用又称为“黑箱复用”。

迪米特法则

  • 定义

    指一个软件实体应尽可能少的与其他实体发生相互作用。当一个模块修改时,就会尽量少的影响其他模块,这是对软件实体之间通信的限制,它要求软件实体之间通信的宽度和深度。

  • 分析

    在迪米特法则中,对于一个对象,其朋友包括以下几类:

    1. 当前对象本身(this)
    2. 以参数形式传入到当前对象方法中的对象
    3. 当前对象的成员对象
    4. 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友
    5. 当前对象所创建的对象

    任何对象如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。

  • 分类

    • 狭义的迪米特法则

      如果两个类之间不必彼此通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。狭义的迪米特法则可以降低类之间的耦合,但也会造成系统不同模块之间通信效率降低,使得系统的不同模块之间不容易协调。

    • 广义的迪米特法则

      指对象之间的信息流量、流向以及信息的影响的控制,主要是对信息隐藏的控制。信息的隐藏可以使各个子系统之间脱耦,每一个模块不依赖于其他模块存在,因此每一个模块都可以独立地在其他地方使用。

猜你喜欢

转载自www.cnblogs.com/Yee-Q/p/12410179.html