[转]面向对象的六大原则

现在编程的主流语言基本上都是面向对象的。如C#,C++,JAVA。我们在使用时,已经构造了一个个的类。但是往往由于我们在类内部或外部的设计上存在种种问题,导致尽管是面向对象的语言,却是面向过程的逻辑,甚至维护起来异常困难。每次增加或修改功能都要改动很多的代码,如履薄冰。而面向对象的六大原则主要的目的,就是我们如何设计类,更能很好的利用面向对象的特性。

1)单一职责原则

一个类永远只有一个职责。

  一套软件就像是一个团队,每个类就是团队中的一个成员。团队如果想稳定的发展。这些类就要各司其职,分工明确。如果类之间的功能出现了混淆,那么软件的整体结构就会非常的混乱。就像管理学中的一句话,如果一个职责由每个员工负责,那么这个职责就没有员工在负责。 这个原则的概念非常简单,也是非常基础的。很多人尽管没有学习过面向对象的思想,但是经常写代码之后也会不自觉的遵守这个原则。 Ps:在遵循单一职责原则的时候,常常会遇到职责扩散的问题。什么是职责扩散呢?这里简单说下,在日志生活中,我们在分类职责时,发现很多平常不受重视的职责,但是这些职责又不能忽视。于是就依次累加,最后分起类来会无穷无尽(有兴趣的读者可以参考下长尾定理)。为了解决这种问题,我们就需要有一些类,他的职责比较综合(类似于“其它”)。类似于一个帮助类。但是这个类又不能太复杂了,否则我们就应该考虑怎么把这个类分离开来。究竟这个类的复杂程度到了什么时候情况下,我们就应该拆分呢?这个需要程序员根据软件自身的复杂情况来判断,没有一个统一的标准。

2) 里氏替换原则

“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”

——“继承必须确保超类所拥有的性质在子类中仍然成立“

   这个原则主要是为了体现面向对象的“继承”特征来提出的。 它的主旨就是,能够使用基类的地方,必然也能够透明的使用其子类,并且保证不会出错。为了保证这种透明的无差别的使用,子类在使用时不应该随意的重写父类已经定义好的非抽象的方法。因为这些非抽象方法,类似于某种职能或契约,当父类保持这种约定时,子类也应该遵循并保证该特性,而非修改该特性。 我们在写代码的时候,如果一个参数设定的是基类(或接口、抽象类),那么我们传送子类进去,一样可以正常使用。因为基类相对于父类,只是一个更丰富,更具体,更详细的表现形式。而不应该出现,传入父类运行某种方法没有问题,可是传入子类运行时就报错了。这在日常生活中也可以理解,汽车作为父类,他下面有卡车、轿车。轿车下边又有两厢,三厢等不同的继承。但是无论是哪种汽车(父类)的职能,对于他的子类(卡车或轿车)都应该具有相同的职能,而不是相反的职能。以至于子类的子类(本例中是两厢轿车)也应该拥有汽车一致的功能。

  我们在写代码中,很容易出现复写了父类的方法后,父类的方法发生了改动,而未考虑到子类的方法也需要作出相应的改动,导致代码出现错误。 通俗一点,可以理解为子类是遗传自父类的。他在各种职能上也应该一脉相承自父类。而不应该随意改变。

  Ps 为什么要叫里氏替换原则呢?这是因为最早提出这个理论的人姓里Liskov。这是计算机中少有的以姓氏命名的东西。

3)最少知道原则

Only talk to your immediate friends。(已经第二次引用英文,是不是很厉害23333)

永远只和你的朋友交流。

  我们在学习编程的初期,都会有人告诉我们要遵循“高内聚,低耦合”。而OO中也将“封装”作为对象的基本特征之一。最少知道原则其实体现的就是“高内聚,低耦合”这句话。

(1)低耦合:一个类对于自己依赖的类,知道的越少越好。不要让一个类依赖过多的类。否则这个类很容受外界的影响,并且因为这种影响要改变自身的代码(自身要适应)。

(2)高内聚:将实现逻辑都封装在类的内部,对public方法以外的信息,不轻易暴露给外界。这是由于public对外后,相当于是一种契约,一种许诺。你要再后边的实现中,不断的去兼容这种public,以防止调用它的代码不会报错。 上面这样说,可能有点抽象,这里举个例子。在很多人对另一方的要求,都有一条,社会关系不要复杂。为什么会这样呢?因为一个人如果他和外界的关系越复杂,他就越不稳定,不怕人找事,就怕事找人。或许他的本性是好的,但是周边的龙鱼混杂,三天两头的总会有事。避免这种问题的最好办法,就是一开始就做一个安静的美男子。

4)接口隔离原则

一个类对于另外一个类的依赖应该建立在最小的接口上。

  一个接口定义的过于臃肿,则代表他的每一个实现类都要考虑所有的实现逻辑。如果一个类实现了某个接口,也就是说这个类承载了这个接口所有的功能,维护这些功能成为了自己的职责。这就无形中增加了一个类的负担。

这里有两点需要说明一下:

(1)接口定义的小,但是要有限度。对接口细化可以增加灵活性,但是过度细化则会使设计复杂化。同时接口的使用率不高,提高了代码的维护成本。这种极端的体现就是每个接口只含有一个方法,这显然是不合适的。

(2)接口隔离原则和单一原则的区别

共同点:都是尽可能的缩小涉及的范围。

不同点:单一原则主要是指封装性。他针对的是一个类、一个方法,是从对象的角度考虑的。而接口隔离原则是指类之间的耦合应该保持的一个度。他针对的是类(对象)和类(对象)之间的关系。如果说单一原则指的是思想单纯,那么接口隔离指的就是社会关系简单啦。

5)依赖置换原则

这个原则的名字比较唬人,我们先看看他的内容究竟是什么。在设计模式中对该原则有两句经典的描述:

(1)高层模块不应该依赖底层模块。两者都应该依赖抽象。

(2)抽象不应该依赖细节,细节应该依赖抽象。

  这两句话的含义是:高层模块不应该依赖底层模块。两者应该通过抽象的东西进行关系链接(抽象的东西是指接口或者抽象类)。其次抽象类或者一个接口不应该依赖某个实现类。而这些实现类反而应该依赖于这个抽象类的设定。

通俗一点的说法就是,模块之间不应该直接产生调用关系(这是旧有的调用关系),两者应该通过面向接口(或者理解为面向设定的契约)进行编程。而这些契约和接口更不应该以来自底层模块而设定。这些底层模块反而应该遵守这些契约。因为契约(抽象类、接口)相对于哪些实现代码,更不会改变,也就是更稳定。所以依赖置换原则又叫作面向接口编程或面向契约编程。本意就是调整原来的依赖关系,重行进行了设定。

6)开闭原则

开闭原则是指:一个软件、一套系统在开发完成后,当有增加或修改需求时,应该对拓展代码打开,对修改原有代码关闭。

  类一旦确定,就不应该再对其功能发生修改。这是面向对象设计中,最重要最核心的原则。方案发布后,我们最担心的是什么?就是需求的变化,而需求一旦有变化,就要修改代码。大部分的bug往往就是这时候引入的。因为修改代码时,我们往往将重点放在,如何解决当前bug上,反而没有注意因为这个修改,对原有设计的影响。

这条原则没有具体的指导要求,是前边五条原则的根本。

ps,这六个面向对象的原则,并不是是和否的问题,也不是遵守和不遵守的问题。而是遵守的多和遵守的少的问题。我在文中也多次强调,我们在设计时,应该注意把握一个度。诚然尽可能的遵守这些原则,会使代码维护起来更容易。但是维护粒度过细,所需要的设计和开发成本成倍增加,这显然是舍本逐末的。如图,面向对象开发原则可以从以下这个坐标图展示,不论是哪个维度,他的值都不应该过满,甚至溢出,当然也不能很低,保持一个适当的度即可。

原文链接:

面向对象的六大原则

时间: 2024-10-12 20:49:23

[转]面向对象的六大原则的相关文章

面向对象的六大原则

现在编程的主流语言基本上都是面向对象的.如C#,C++,JAVA.我们在使用时,已经构造了一个个的类.但是往往由于我们在类内部或外部的设计上存在种种问题,导致尽管是面向对象的语言,却是面向过程的逻辑,甚至维护起来异常困难.每次增加或修改功能都要改动很多的代码,如履薄冰.而面向对象的六大原则主要的目的,就是我们如何设计类,更能很好的利用面向对象的特性. 1)单一职责原则 一个类永远只有一个职责. 一套软件就像是一个团队,每个类就是团队中的一个成员.团队如果想稳定的发展.这些类就要各司其职,分工明确

0608pm单例模式and面向对象的六大原则

//把类控制住,不让外界造她的对象class DA{ public $name; static private $dx;//存放对象的变量 //将构造变为私有,外界没法造对象 private function __construct() { } //提供一个造对象的方法 static function CreateDX() { if(empty(self::$dx))//判断是否为空 { self::$dx=new DA();//如果是空的就new一个对象放在dx里面 } return self

面向对象的六大原则(推荐)

要把软件做得非常灵活又要便于维护是一个很困难的事情.灵活的软件他的结构就复杂,维护起来就困难.有得必有失,关键就在于如何处理这两者,使得大于失.软件的设计开发应遵循以下六大原则: 1.   OCP 全称:“Open-Closed Principle” 开放-封闭原则 说明:对扩展开放,对修改关闭. 优点:按照OCP原则设计出来的系统,降低了程序各部分之间的耦合性,其适应性.灵活性.稳定性都比较好.当已有软件系统需要增加新的功能时,不需要对作为系统基础的抽象层进行修改,只需要在原有基础上附加新的模

【读书】一、面向对象的六大原则

一.单一职责 一个类中应该是一组相关性很高的函数.数据的封装 二.开闭原则 软件中的对象(类,模块,函数等)应该对于拓展开放的,对于修改是封闭的 解释:软件生命周期内,因为变化,升级维护等原因需要对旧代码去修改,此时可能会破坏已经测试过的旧代码,所以,应该尽量去通过拓展来修改代码,而不是通过修改旧代码来实现. 其实在现实中,修改原有代码和拓展代码是同时存在的. 三.里氏替换 所有引用基类的地方必须能透明的使用其子类的对象 解释:只要父类能出现的地方,子类都可以出现,而且替换成子类也不会有问题 总

走向灵活软件之路——面向对象的六大原则

一.优化代码的第一步:单一职责原则 英文名:Single Responsibility Principle (SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因. 简单来说,一个类中应该是一组相关性很高的函数.数据的封装. 示例代码: 二.让程序更稳当.更灵活:开闭原则 英文名:Open Close Principle (OCP) 定义:软件中的对象(类.模块.函数等)应该对于扩展是开放的,当时,对于修改是封闭的. 在软件的生命周期中,因为变化.升级和维护等原因需要对软件原有代码进行修改

面向对象的六大原则之 接口隔离原则——ISP

ISP = Interface Segregation Principle ISP的定义如下: 1.客户端不应该依赖他不需要的接口 2.一个类对另外一个类的依赖性应该是建立在最小的接口上 3.不应当将不同的接口合并在一起,形成一个臃肿的大接口,这是对接口的污染 4.使用多个专门的接口要比使用单一的总接口要好 ISP的几个使用原则 1.根据接口隔离原则拆分接口时,首先必须满足单一职责原则: 没有哪个设计可以十全十美的考虑到所有的设计原则,有些设计原则之间就可能出现冲突,就如同单一职责原则和接口隔离

面向对象编程的六大原则(1)--单一职责原则

什么是单一职责 单一职责原则(Single responsibility principle,简称SRP),顾名思义,是指一个类或者一个模块应该有且只有一个职责,它是面向对象编程六大原则之一. 单一职责的粒度 单一职责的粒度,可以是某个方法.某个类.某个程序包甚至某个功能.某个模块(甚至某个系统),每一个层次上都可以进行单一职责设计.下面来举个例子说明一下: 模块级别:某购物平台,包含如下几个模块:用户模块.商品模块.订单模块.库存模块.运输模块.支付模块,每一个模块都已本身的职责:用户模块负责

Java面向对象设计的六大原则

这是设计模式系列开篇的第一篇文章.也是我学习设计模式过程中的总结.这篇文章主要讲的是面向对象设计中,我们应该遵循的六大原则.只有掌握了这些原则,我们才能更好的理解设计模式.我们接下来要介绍以下6个内容. 单一职责原则——SRP 开闭原则——OCP 里式替换原则——LSP 依赖倒置原则——DIP 接口隔离原则——ISP 迪米特原则——LOD 单一职责原则 单一职责原则的定义是就一个类而言,应该仅有一个引起他变化的原因.也就是说一个类应该只负责一件事情.如果一个类负责了方法M1,方法M2两个不同的事

详解设计模式六大原则

设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 借用并改编一下鲁迅老师<故乡>中的一句话,一句话概括设计模式: 希望本无所谓有,无所谓无.这正如coding的设计模式,其实coding本没有设计模式,用的人多了,也便成了设计模式 v六大原