面向对象设计 7 大原则

栏目: 后端 · 发布时间: 6年前

内容简介:面向对象 设计模式

面向对象设计 7 大原则

面向对象设计7大原则

面向对象 设计模式

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

一句话概括 :每一个类应该专注于做一件事情。

高逼格专业描述: 是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因的话,以提高内聚性来减少引起变化的原因。不要为类实现过多的功能点,以保证类实体只有一个引起它变化的原因

非要多说一嘴: 单一职责原则不只是面向对象编程思想所特有的,只要是 模块化的程序设计,都适用单一职责原则

2. 里氏替换原则(Liskov Substitution Principle)

一句话概括:超类/基类存在的地方,子类是可以替换的。【反之不一定可以】

高逼格专业描述: 子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。在父类和子类的具体行为中,必须严格把握继承层次中的关系和特征,将基类替换为子类,程序的行为不会发生任何变化。同时,这一约束反过来则是不成立的,子类可以替换基类,但是基类不一定能替换子类。

里氏替换原则,主要着眼于对抽象和多态建立在继承的基础上,因此只有遵循了里氏替换原则,才能保证继承复用是可靠地。实现的方法是面向接口编程:将公共部分抽象为基类接口或抽象类,通过Extract Abstract Class,在子类中通过覆写父类的方法实现新的方式支持同样的职责。

里氏替换原则是关于继承机制的设计原则,违反了里氏替换原则就必然导致违反开放封闭原则 【解释:实现开闭原则的关键是抽象化,而里氏代换原则中的基类和子类的继承关系正是抽象化的具体体现,所以里氏代换原则是对实现抽象化的具体步骤的规范。】

里氏替换原则能够保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余,避免运行期的类型判别。

非要多说一嘴: 尽量使用精准的抽象类或者接口【子类和父类划分精准】,里氏代换原则是要求我们在使用继承时,必须满足一定的条件。不能为了复用,一味去继承。

3. 依赖倒置原则(Dependence Inversion Principle)

一句话概括 :实现尽量依赖抽象,不依赖具体实现。【可以映射为 活着与吃饭的关系 ,活着不是为了吃饭,但是吃饭为了活着。】

高逼格专业描述 : 我们知道,依赖一定会存在于类与类、模块与模块之间。当两个模块之间存在紧密的耦合关系时,最好的方法就是 分离 接口和实现:在依赖之间定义一个抽象的接口使得高层模块调用接口,而基础层模块实现接口的定义,以此来有效控制耦合关系,达到依赖于抽象的设计目标。

抽象的稳定性决定了 系统的稳定性 ,因为抽象是 不变的 ,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。

依赖于抽象是一个通用的原则,而某些时候依赖于细节则是在所难免的,必须权衡在抽象和具体之间的取舍,方法不是一层不变的。 依赖于抽象,就是对面向接口编程,不要对实现编程

非要多说一嘴: 依赖倒置原则就是要求调用者和被调用者都依赖抽象,这样两者没有直接的关联和接触,在变动的时候,一方的变动不会影响另一方的变动。 面向抽象编程,解耦调用和被调用者

4. 接口隔离原则(Interface Segregation Principle)

一句话概括 :应当为客户端提供尽可能小的单独的接口,而不是提供大的总的接口。

高逼格专业描述 : 接口隔离原则可以说是 单一职责的必要手段 ,它的含义是尽量 使用职能单一的接口 ,而不使用职能复杂、全面的接口。很好理解,接口是为了让子类实现的,如果 子类想达到职能单一 ,那么 接口也必须满足职能单一 。相反,如果接口融合了多个不相关的方法,那它的子类就被迫要实现所有方法,尽管有些方法是根本用不到的。这就是 接口污染 。【大接口存在明显的弊端,会导致实现的类型必须完全实现该接口的所有方法、属性等;而某些时候,实现类型并非需要所有的接口定义,在设计上这是“浪费”,而且在实施上这会带来潜在的问题,对大接口的修改将导致一连串的客户端程序需要修改,有时候这是一种灾难。在这种情况下,将大接口分解为多个特点的定制化方法,使得客户端仅仅依赖于它们的实际调用的方法,从而解除了客户端不会依赖于它们不用的方法。】

非要多说一嘴 : 拆分,从接口开始。

5. 迪米特法则(Law Of Demeter)

一句话概括 :又叫最少知识原则,一个对象对另一个对象知道的越少越好,即一个软件实体应当尽可能少的与其他实体发生相互作用。

高逼格专业描述 : 迪米特原则要求尽量的封装,尽量的独立,尽量的使用低级别的访问修饰符。这是封装特性的典型体现。 一个类如果暴露太多私用的方法和字段,会让调用者很茫然。并且会给类造成不必要的判断代码。所以,我们使用尽量低的访问修饰符,让外界不知道我们的内部。这也是面向对象的基本思路。这是迪米特原则的一个特性,无法了解类更多的私有信息。 另外,迪米特原则要求类之间的直接联系尽量的少,两个类的访问,通过第三个中介类来实现。

非要多说一嘴 : 不和陌生人说话,有事去中介

6. 开闭原则(Open Close Principle)

一句话概括 :面向扩展/修改开放,面向修改关闭。

高逼格专业描述 : 其核心思想是:软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。开放封闭原则主要体现在两个方面1、对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。2、对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对其进行任何尝试的修改。 实现开开放封闭原则的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以修改就是封闭的;而通过面向对象的继承和多态机制,又可以实现对抽象类的继承,通过覆写其方法来改变固有行为,实现新的拓展方法,所以就是开放的。

非要多说一嘴 : “需求总是变化”没有不变的软件,所以就需要用封闭开放原则来封闭变化满足需求,同时还能保持软件内部的封装体系稳定,不被需求的变化影响。 一条放在第一位来理解,它的含义是对扩展开放,对修改关闭。解释一下就是,我们写完的代码,不能因为需求变化就修改。我们可以通过新增代码的方式来解决变化的需求。

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

7. 组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP)

一句话概括 :尽量使用合成/聚合达到复用,尽量少用继承。

高逼格专业描述 : 此原则的含义是,如果只是达到代码复用的目的,尽量使用组合与聚合,而不是继承。这里需要解释一下,组合聚合只是引用其他的类的方法,而不会受引用的类的继承而改变血统。 继承的耦合性更大【使用继承的方式将两个不相干的类联系在一起,也会违反里氏代换原则】,比如一个父类后来添加实现一个接口或者去掉一个接口,那子类可能会遭到毁灭性的编译错误,但如果只是组合聚合【类与类之间的耦合度降低】,只是引用类的方法,就不会有这种巨大的风险,同时也实现了复用。

非要多说一嘴 : 意思就是我只是用你的方法,我们不一定是同类。

在学习面向对象七大设计原则时需要注意以下几点:

a)高内聚、低耦合和单一职能的“冲突”

实际上,这两者是一回事。内聚,要求一个类把所有相关的方法放在一起,初看是职能多,但有个“高”,就是要求把联系非常紧密的功能放在一起,也就是说,从整体看,是一个职能的才能放在一起,所以,两者是不同的表述而已。

这里很多人理解成复合类,但复合类不是高内聚,而是杂乱的放在一起,是一种设计失误而已。

b)多个单一职能接口的灵活性和声明类型问题

如果一个类实现多个接口,那么这个类应该用哪个接口类型声明呢?应该是用一个抽象类来继承多个接口,而实现类来继承这个接口。声明的时候,类型是抽象类。

c)最少知识原则和中介类泛滥两种极端情况

这是另一种设计的失误。迪米特原则要求类之间要用中介来通讯,但类多了以后,会造成中介类泛滥的情况,这种情况,我们可以考虑中介模式,用一个总的中介类来实现。

当然,设计模式都有自己的缺陷,迪米特原则也不是十全十美,交互类非常繁多的情况下,要适当的牺牲设计原则。

d)继承和组合聚合复用原则的“冲突”

继承也能实现复用,那这个原则是不是要抛弃继承了?不是的。

继承更注重的是“血统”,也就是什么类型的。而组合聚合更注重的是借用“技能”。并且,组合聚合中,两个类是部分与整体的关系,组合聚合可以由多个类的技能组成。在C#和 Java 中只有单继承。

这个原则不是告诉我们不用继承了,都用组合聚合,而是在“复用”这个点上,我们优先使用组合聚合。

面向对象设计原则的共性问题:

1、这么多设计模式,都要学习和使用么?

答:我们只是掌握总体的原则,然后学习常用的就行了。实际开发中也不是每种设计模式都会经常用到。因为归根结底,设计模式也好,架构也好,都是为需求服务的,没有需求业务模型,不能生搬硬套模式。我们在学习的时候,多学一些总是好的,但只是为了开阔自己的眼界。

2、设计模式是规范么?是不是好的程序必须用设计模式?

答:严格来说,好的程序遵循的是设计原则,而非设计模式。现在就出现很多新的演变出来的模式,这些都是因为出现了新业务的原因,设计模式不是规范,只是一种借鉴。

3、使用设计模式会不会增加开发难度?

答:开发阶段会的,而且会延长开发时间。但一个项目或产品从开始到结束,开发只是其中很小的一部分,考虑到维护和扩展成本,才会出现设计模式。从整体考虑,设计模式是减少了开发时间和成本的。


以上所述就是小编给大家介绍的《面向对象设计 7 大原则》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Think Python

Think Python

Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99

Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具