面向对象七大设计原则

面向对象七大设计原则

1、  开闭原则

2、  里氏替换原则

3、  单一职责原则

4、  接口隔离原则

5、  依赖倒置原则

6、  迪米特原则

7、组合/聚合复用原则

 

知识点关联

学习面向对象的设计模式,是深入面向对象思想的钥匙。通过大师级的微妙案例。我们能够开阔自己的认知。

在学习面向对象设计七大原则之前,我们要对主要的封装、继承、多态思想有足够的了解。对抽象类和接口也要有足够的编码能力,由于设计模式是以上知识点的综合应用。

另外。在接触详细的设计模式之前,面向对象的七大设计原则会让你知道,设计模式出现的必定性和意义所在。

 

1、 每一种设计思想的精准含义,详细例如以下:

先从总体认识这七种设计思想。

一、开闭原则:

这一条放在第一位来理解,它的含义是对扩展开放,对改动关闭

解释一下就是,我们写完的代码,不能由于需求变化就改动。我们能够通过新增代码的方式来解决变化的需求。

当然,这是一种理想的状态,在现实中。我们要尽量的缩小这样的改动。

再解释一下这条原则的意义所在,我们採用逆向思维方式来想。假设每次需求变动都去改动原有的代码,那原有的代码就存在被改动错误的风险。当然这当中存在有意和无意的改动。都会导致原有正常执行的功能失效的风险,这样非常有可能会展开可怕的蝴蝶效应。使维护工作剧增。

说究竟,开闭原则除了表面上的可扩展性强以外。在企业中更看重的是维护成本。

所以,开闭原则是设计模式的第一大原则,它的潜台词是:控制需求变动风险。缩小维护成本。

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

二、里氏替换选择:

此原则的含义是子类能够在不论什么地方替换它的父类。解释一下。这是多态的前提,我们后面非常多所谓的灵活,都是不改变声明类型的情况下,改变实例化类来完毕的需求变更。

当然,继承的特性看似天然就满足这个条件。

但这里更注重的是继承的应用问题。我们必须保证我们的子类和父类划分是精准的。

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

三、单一职责原则:

单一职责的含义是:类的职责单一,引起类变化的原因单一。解释一下。这也是灵活的前提,假设我们把类拆分成最小的职能单位,那组合与复用就简单的多了,假设一个类做的事情太多。在组合的时候,必定会产生不必要的方法出现。这实际上是一种污染。

举个样例。我们在绘制图案的时候,用“点”组成图和用“直线”组成图,哪个更灵活呢?一定是“点”,它能够绘制不论什么图形,而直线仅仅能绘制带有直线条的图案。它起码无法画圆。

单一职责的潜台词是:拆分到最小单位,解决复用和组合问题。

四、接口隔离原则:

接口隔离原则能够说是单一职责的必要手段。它的含义是尽量使用职能单一的接口。而不使用职能复杂、全面的接口。

非常好理解,接口是为了让子类实现的,假设子类想达到职能单一。那么接口也必须满足职能单一。

相反,假设接口融合了多个不相关的方法,那它的子类就被迫要实现全部方法,虽然有些方法是根本用不到的。

这就是接口污染。

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

五、依赖倒置原则:

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

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

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

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

六、迪米特原则:

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

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

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

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

七、组合/聚合复用原则:

此原则的含义是。假设仅仅是达到代码复用的目的。尽量使用组合与聚合。而不是继承

这里须要解释一下,组合聚合仅仅是引用其它的类的方法。而不会受引用的类的继承而改变血统。

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

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

 

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

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

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

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

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

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

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

这是还有一种设计的失误。

迪米特原则要求类之间要用中介来通讯,但类多了以后,会造成中介类泛滥的情况,这样的情况,我们能够考虑中介模式,用一个总的中介类来实现。

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

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

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

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

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

 

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

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

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

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

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

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

答:开发阶段会的。并且会延长开发时间。但一个项目或产品从開始到结束。开发仅仅是当中非常小的一部分,考虑到维护和扩展成本,才会出现设计模式。

从总体考虑,设计模式是降低了开发时间和成本的。

 

posted @ 2017-08-14 14:41  yfceshi  阅读(533)  评论(0编辑  收藏  举报