设计模式的六大原则

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

内容简介:要介绍设计模式,就要先介绍它的六大原则。它们分别是单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则、迪米特原则(最少知识原则)、接口隔离原则(接口多样化、专业化)。通俗地讲就是我们不要让一个类承担太多的职责。如果一个类承担的职责太多,就等于把这些职责耦合在一起,这种耦合会导致脆弱设计,当变化发生时,设计会遭到破坏。比如说在MVP模式里面,fragment类就只负责展示数据,如果里面还负责数据获取等,到时维护起来就会很麻烦。

要介绍设计模式,就要先介绍它的六大原则。它们分别是单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则、迪米特原则(最少知识原则)、接口隔离原则(接口多样化、专业化)。

单一职责原则

通俗地讲就是我们不要让一个类承担太多的职责。如果一个类承担的职责太多,就等于把这些职责耦合在一起,这种耦合会导致脆弱设计,当变化发生时,设计会遭到破坏。

比如说在MVP模式里面,fragment类就只负责展示数据,如果里面还负责数据获取等,到时维护起来就会很麻烦。

开放封闭原则

开放封闭,阐释起来就两点:对于拓展是开放的,对于修改是封闭的。在程序开发中,需求是要变化的。如果有新需求的话,就要去更改原来的类,这样做的成本有点高。所以在设计程序的时候,面对需求的改变应尽可能地保证相对稳定,尽量通过扩展的方式去实现新功能。

这里给一个例子(来自网上)

我们现在在经营一家书店,书店里自然售卖书籍。所以我们定义了以下类。

设计模式的六大原则

书籍接口以及书籍类别:

设计模式的六大原则

书店实现:

设计模式的六大原则

运行结果:

设计模式的六大原则

项目投产,书店盈利,但为扩大市场,书店决定,40元以上打8折,40元以下打9 折。如何解决这个问题呢?

第一个办法:修改接口。在IBook上新增加一个方法getOffPrice(),专门进行打折,所有实现类实现这个方法。

但是这样修改的后果就是实现类NovelBook要修改,BookStore中的main方法也修改,同时Ibook作为接口应该是稳定且可靠的,不应该经常发生变化,否则接口做为契约的作用就失去了效能,其他不想打折的书籍也会因为实现了书籍的接口必须打折,因此该方案被否定。

第二个办法:修改实现类。修改NovelBook 类中的方法,直接在getPrice()中实现打折处理,这个应该是大家在项目中经常使用的就是这样办法,通过class文件替换的方式可以完成部分业务(或是缺陷修复)变化,该方法在项目有明确的章程(团队内约束)或优良的架构设计时,是一个非常优秀的方法。

但是该方法还是有缺陷的,例如采购书籍人员也是要看价格的,由于该方法已经实现了打折处理价格,因此采购人员看到的也是打折后的价格,这就产生了信息的蒙蔽效果,导致信息不对称而出现决策失误的情况。该方案也不是一个最优的方案。

也就是我们既需要能够获取它的原价格也需要获取它的打折价格。这个方法只能获取一种价格

第三个办法:最优方案,通过扩展实现变化。增加一个子类 OffNovelBook,覆写getPrice方法,高层次的模块(也就是static静态模块区)通过OffNovelBook类产生新的对象,完成对业务变化开发任务。好办法,风险也小,我们来看类图:

设计模式的六大原则

书籍接口以及书籍类别:

设计模式的六大原则

书店实现:

设计模式的六大原则

运行结果:

设计模式的六大原则

里氏替换原则

里氏替换原则就是,将一个基类对象替换成其子类对象,程序就不会产生任何错误和异常。反之则不成立,如果一个子类替换成基类,程序可能会产生错误。

我们来看一个违反里氏替换原则的例子。

我们需要完成一个两数相减的功能,由类Subtraction来负责:

设计模式的六大原则

运行结果:

设计模式的六大原则

后来,我们需要增加一个新的功能:完成两数相加,然后再与100求和,由类Add来负责。所以类Add继承类Subtraction后,代码如下:

设计模式的六大原则

我们发现原来运行正常的相减功能发生了错误。原因就是类Add在给方法起名时无意中重写了父类的方法,造成所有运行相减功能的代码全部调用了类Add的重写后的方法,造成原本运行正常的功能出现了错误。

在这里,父类被子类替换后,原来的程序出现了错误。

在实际编程中,我们常会通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的几率非常大。如果非要重写父类的方法,比较通用的做法是:原来的父类和子类都继承一个更通俗的基类,如接口、抽象类。

所以我们在运用里氏替换原则时,应该尽量把父类设计成抽象类或者接口。

依赖倒置原则

依赖倒置原则指的是:模块间的依赖通过抽象(抽象类或者接口)发生,实体类不应该直接发生依赖关系。如果类与类产生直接依赖,就会直接耦合,修改的时候就会同时修改依赖者的代码,限制了可扩展性。

一句话概括就是,模块与模块之间的依赖应该是通过接口或者抽象类。

例如MVP里面的Present模块和View模块

迪米特原则

迪米特原则要求我们在设计系统时,就应该尽量减少对象之间的交互,这两个对象对彼此要尽可能地少去了解。如果两个对象不必直接通信,就不应当发生直接的相互作用。如果其中一个对象需要调用另一个对象的某一个方法,则可以通过第三者转发这个调用。

一句话概括就是,通过引入一个合适的第三者来降低现有对象之间的耦合度。

例如MVP里面的MVP,第三者是Present

接口隔离原则

建立单一接口,而不是建立庞大的接口。尽量细化接口,接口中的方法应当尽量少。也就是说我们要对每个类建立专用接口,而不是建立一个庞大的接口供所有依赖它的类调用。注意接口尽量小,但是要有限度,不要过小造成设计复杂化。

例如MVP里面的契约接口。


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

查看所有标签

猜你喜欢:

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

特斯拉之父

特斯拉之父

竹内一正 / 千太阳 / 中信出版社 / 2014-12 / 39.00

马斯克的成就前无古人地跨越了各个领域,曾大起大落,成为亿万富翁后,又曾濒临破产。他凭借极强的控制欲、坚强的意志力把人生浓缩得异常精彩,拓展了人类对自身智力与能力限度的想象。乔布斯离开了,马斯克来了,后者离人更远,离神更近。 他的创业故事就是一部真实的好莱坞大片 美国《财富》杂志 “2013年度商业人物” 史上最富激情、传奇、未来感的企业家 他是个外表优雅的生意人、太空的挑战......一起来看看 《特斯拉之父》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具