面向对象的七大设计原则

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

每一个类应该专注于做一件事情。

每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都需要遵循这一重要原则。

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

超类存在的地方,子类是可以替换的。

子类型必须能够替换掉它们的父类型。注意这里的能够两字。有人也戏称老鼠的儿子会打洞原则。

所有引用父类的地方必须能透明地使用其子类的对象。子类可以扩展父类的功能,但不能改变父类原有的功能,即:子类可以实现父类的抽象方法,子类也中可以增加自己特有的方法,但不能覆盖父类的非抽象方法。当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

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

实现尽量依赖抽象,不依赖具体实现。

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。中心思想是面向接口编程

在实际编程中,我们一般需要做到如下3点:

1. 低层模块尽量都要有抽象类或接口,或者两者都有。

2. 变量的声明类型尽量是抽象类或接口。

3. 使用继承时遵循里氏替换原则。

采用依赖倒置原则尤其给多人合作开发带来了极大的便利,参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。

 依赖倒置原则就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。

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

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

客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

我们在代码编写过程中,运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。设计接口的时候,只有多花些时间去思考和筹划,就能准确地实践这一原则。

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

又叫最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用。

即:一个对象应该对其他对象保持最少的了解。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。简单定义为只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系。故过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

6. 开闭原则(Open Close Principle)

面向扩展开放,面向修改关闭。

更通俗一点讲,也就是:软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,去扩展新功能。开闭原则中原有“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于代码的修改是封闭的,即不应该修改原有的代码。

开闭原则具有理想主义的色彩,说的很抽象,它是面向对象设计的终极目标。其他几条原则,则可以看做是开闭原则的实现。我们要用抽象构建框架,用实现扩展细节。

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

尽量使用合成/聚合达到复用,尽量少用继承。原则: 一个类中有另一个类的对象。

尽量使用合成/聚合,尽量不要使用类继承。换句话说,就是能用合成/聚合的地方,绝不用继承。

为什么要尽量使用合成/聚合而不使用类继承?

1. 对象的继承关系在编译时就定义好了,所以无法在运行时改变从父类继承的子类的实现

2. 子类的实现和它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化

3. 当你复用子类的时候,如果继承下来的实现不适合解决新的问题,则父类必须重写或者被其它更适合的类所替换,这种依赖关系限制了灵活性,并最终限制了复用性。

(C) 房上的猫 。 保留所有权利。  https://www.cnblogs.com/lsy131479/

如需转载,请注明出处!!!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习网

学习Java需吃透这些基本概念

学习好比盖房子,打地基好很重要,房了能盖多高关键看地基;学习同样道理,基础知识是以后学习一切技术的必要条件,我们在准备学习一门开发语言时,首先要学习它的基础,不...

22610
来自专栏猿人谷

[你必须知道的.NET] 第四回:后来居上:class和struct

本文将介绍以下内容: • 面向对象基本概念 • 类和结构体简介 • 引用类型和值类型区别 1. 引言 提起class和struct,我们首先的感觉是语法几乎相...

17710
来自专栏深度学习之tensorflow实战篇

Python中的__init__()方法整理中(两种解释)

解释一:看懂了就不用看第二种了 __init__()方法是Python学习当中重要的基础知识,__init__()方法意义重大的原因有两个。第一个原因是在对...

3546
来自专栏一个会写诗的程序员的博客

13.10 Scala中使用JSON.toJSONString报错:ambiguous reference to overloaded definition13.10 Scala中使用JSON.t

在Java代码中,我们是不推荐带有变长参数的方法重载的。这样的代码调用人类阅读起来会感到“模糊”。

673
来自专栏Java学习网

Java中提高代码复用性的方法及规范总结

一个好的程序员一定是用最少的代码实现最多的功能,代码复用是程序员所追求和期望的,这也是Java语言所提倡的;根据以往开发经验整理了一些能够提高代码复用性方法和规...

2567
来自专栏java 成神之路

浅谈UML类图中类之间的5种关系

3216
来自专栏Java面试笔试题

简述一下你了解的设计模式

所谓设计模式,就是一套被反复使用的代码设计经验的总结(情境中一个问题经过证实的一个解决方案)。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠...

454
来自专栏斑斓

作为Scala语法糖的设计模式

Scala算是一门博采众家之长的语言,兼具OO与FP的特性,若使用恰当,可以更好地将OO与FP的各自优势发挥到极致;然而问题也随之而来,倘若过分地夸大OO特性,...

3185
来自专栏Phoenix的Android之旅

什么是策略模式

策略模式应该是Java设计模式中最简单的一种模式, 它的核心思想是,一个类的行为可以在运行时动态改变,有不同的实现逻辑。

743
来自专栏Linyb极客之路

UML类图(上):类、继承和实现

对于一个程序员来说,在工作的开始阶段通常都是别人把东西设计好,你来做。伴随着个人的成长,这个过程将慢慢变成自己设计一部分功能来实现,自己实现。如果要自己设计,无...

963

扫描关注云+社区