六种设计原则

 

                                                    六种设计原则

设计模式(面向对象)有七大原则,分别是:

  1.开放-封闭原则

       2.里氏代换原则

      3.接口隔离原则

  4.依赖倒转原则

  5.迪米特法则(也称为最小知识原则)

   6.合成/聚合复用原则

 

一、开闭原则:概念:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。模块应该尽量在不修改原代码的情况下进行扩展。

开闭原则(OCP)

软件实体应当对扩展开放,对修改关闭

                       这一条放在第一位来理解,它的含义是对扩展开放,对修改关闭。解释一下就是,我们写完的代码,不能因为需求变化就修改。我们可以通过新增代码的方式来解决变化的需求。当然,这是一种理想的状态,在现实中,我们要尽量的缩小这种修改。再解释一下这条原则的意义所在,我们采用逆向思维方式来想。如果每次需求变动都去修改原有的代码,那原有的代码就存在被修改错误的风险,当然这其中存在有意和无意的修改,都会导致原有正常运行的功能失效的风险,这样很有可能会展开可怕的蝴蝶效应,使维护工作剧增。说到底,开闭原则除了表面上的可扩展性强以外,在企业中更看重的是维护成本。所以,开闭原则是设计模式的第一大原则,它的潜台词是:控制需求变动风险,缩小维护成本。

以下几种原则,都是为此原则服务的。

注意事项:

  1.通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法。

  2.参数类型、引用对象尽量使用接口或者抽象类,而不是实现类

  3.抽象层尽量保持稳定,一旦确定不允许修改。



二、里氏替换选择:概念:里氏代换原则是面向对象设计的基本原则之一。即任何基类可以出现的地方,子类一定可以出现。里氏代换原则是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受影响时,基类才能被真正复用,而衍生类也能够在积累的基础上增加新的行为,里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。在基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

里氏代换原则(LSP)

所有引用基类的地方必须透明的使用其子类的对象

            子类对象可以代替父类对象,但是反过来,父类对象不可以代替子类对象

此原则的含义是子类可以在任何地方替换它的父类。解释一下,这是多态的前提,我们后面很多所谓的灵活,都是不改变声明类型的情况下,改变实例化类来完成的需求变更。当然,继承的特性看似天然就满足这个条件。但这里更注重的是继承的应用问题,我们必须保证我们的子类和父类划分是精准的。

里氏替换原则的潜台词是:尽量使用精准的抽象类或者接口。


三、接口隔离原则:概念:客户端不应该依赖他不需要的接口,类间的依赖关系应建立在最小的接口上。

单一职责原则(SRP)

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

接口隔离原则可以说是单一职责的必要手段,它的含义是尽量使用职能单一的接口,而不使用职能复杂、全面的接口。很好理解,接口是为了让子类实现的,如果子类想达到职能单一,那么接口也必须满足职能单一。

相反,如果接口融合了多个不相关的方法,那它的子类就被迫要实现所有方法,尽管有些方法是根本用不到的。这就是接口污染。

接口隔离原则的潜台词是:拆分,从接口开始。



 

四、依赖倒置原则:概念:依赖倒转原则是程序要依赖于抽象接口,不要依赖于具体实现。简单的来说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块的耦合。

依赖倒转原则(DIP)

高层模块不应该依赖低层模块,他们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象

想要理解依赖倒置原则,必须先理解传统的解决方案。面相对象的初期的程序,被调用者依赖于调用者。也就是调用者决定被调用者有什么方法,有什么样的实现方式,这种结构在需求变更的时候,会付出很大的代价,甚至推翻重写。

依赖倒置原则就是要求调用者和被调用者都依赖抽象,这样两者没有直接的关联和接触,在变动的时候,一方的变动不会影响另一方的变动。

其实,依赖倒置和前面的原则是相辅相成的,都强调了抽象的重要性。

依赖倒置的潜台词是:面向抽象编程,解耦调用和被调用者。

注意事项:

  1.高层模块不应该依赖于低层模块。两个都应该依赖抽象。

  2.抽象不应该依赖结节。细节应依赖于抽象。


五、迪米特原则:

迪米特法则(LoD)

每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位

迪米特原则要求尽量的封装,尽量的独立,尽量的使用低级别的访问修饰符。这是封装特性的典型体现。

一个类如果暴露太多私用的方法和字段,会让调用者很茫然。并且会给类造成不必要的判断代码。所以,我们使用尽量低的访问修饰符,让外界不知道我们的内部。这也是面向对象的基本思路。这是迪米特原则的一个特性,无法了解类更多的私有信息。

另外,迪米特原则要求类之间的直接联系尽量的少,两个类的访问,通过第三个中介类来实现。

迪米特原则的潜台词是:不和陌生人说话,有事去中介。


六、组合/聚合复用原则:概念:合成/聚合复用原则经常又叫做合成复用原则,就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分,新的对象通过这些对象的委派达到复用已有功能的目的。他的设计原则是:要尽量使用合成/聚合,尽量不要使用继承。

合成复用原则(CRP)

优先使用对象组合,而不是继承来达到复用的目的

此原则的含义是,如果只是达到代码复用的目的,尽量使用组合与聚合,而不是继承。这里需要解释一下,组合聚合只是引用其他的类的方法,而不会受引用的类的继承而改变血统。

继承的耦合性更大,比如一个父类后来添加实现一个接口或者去掉一个接口,那子类可能会遭到毁灭性的编译错误,但如果只是组合聚合,只是引用类的方法,就不会有这种巨大的风险,同时也实现了复用。

组合聚合复用原则的潜台词是:我只是用你的方法,我们不一定是同类。



简单总结一下开闭原则,里氏代换原则,依赖倒转原则之间的关系:开闭原则是目标,里氏代换原则是基础,而依赖倒转原则是手段。他们相辅相成,相互补充。共同使我们的软件具有良好的扩展性。

posted @ 2018-01-14 22:41  秋风伊人  阅读(448)  评论(0编辑  收藏  举报