设计模式-----六大设计原则,成为优秀程序员的必经之路

编程是需要有一定的原则的,没有一定的原则,编出来的代码只是一堆糟糕的代码:
下面我们就介绍这六大原则:
单一职责原则、里氏替换原则、依赖倒置原则(面向抽象编程)、接口隔离原则、迪米特原则(最少知识原则)、开闭原则。

1. 单一职责原则:

一个类只有一个引起这个类变化的原因。即一个类只完成一个功能,如果做不到一个类只完成一个功能,最少要保证一个方法只完成一个功能。
我们很多时候,为了区分功能模块,总是把一类的相关性强的功能放在一个类里面处理,单一职责原则就是尽量一个类一个职责。比如汽车工厂类,就只要负责汽车的生产,汽车销售类,就只要负责汽车的销售。编程的这个单一职责原则,有它的优点:那个职能出错了,就能按照职责来寻找到相应的类。而且不会因为功能耦合来影响其他功能。

2. 里氏替换原则

凡是父类出现的地方都可以用子类代替并且原功能没有发生变化,子类不应该覆盖父类的非抽象方法。
对于这个原则,有两种定义

定义一:

如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

定义二:

所有引用基类的地方必须能透明地使用其子类的对象。
很多人对这个原则的名字很困惑,为什么要使用这个奇怪的名字。其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的。

问题由来:

有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。

解决方案:

当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。
继承包含这样一层含义:父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。

注意:

继承作为面向对象三大特性之一,在给程序设计带来巨大便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加了对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能会产生故障。

3. 依赖倒置原则

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。(面向接口或者抽象编程)

问题由来:

类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:

将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。

依赖倒置原则基于这样一个事实:

相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

4. 接口隔离原则

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

问题由来:

类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。

解决方案:

将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。

整理一下:

假设接口I有方法1、方法2、方法3、方法4、方法5
类C和类D实现了接口I
类A组合类C并且需要调用C中的方法1、方法2、方法3
类B组合类D并且需要调用C中的方法1、方法4、方法5
根据以上的条件限制,我们会发现
类A中的C,方法4和方法5对于A来说就是无用的方法
类B中的D,方法2和方法3对于A来说就是无用的方法
假设我们要要改动方法2或者方法4的实现,类C和类D都要修改
为了避免这种修改
我们可以把接口分声明方法1的接口I1,由类E去实现;还有声明方法2和方法3的接口I2,由类F去实现;以及声明方法4和方法5的接口I3,由类G去实现。
这样我们类A就只需要组合类E和类F,类B就只要组合类E和类G,这样修改方法2,和方法4,类E就不需要改动,只要修改相应的实现类就好,EFG也不需要实现本来自己不需要实现的方法。

5. 迪米特法则

一个对象应该对其他对象保持最少的了解。(最少知识原则)

问题由来:

类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案:

尽量降低类与类之间的耦合。

案例:

假设我们要使用陶瓷杯子,在没有生产被子的工厂的时候,我们需要自己去做,这个时候我们要去收集粘土,去掉粘土里的空气,让被子成型,上釉,最后再高温烧制,最后我们才能使用。
如果我们有生产陶瓷杯子的自产自销工厂,那么这些制作杯子的过程都是工厂完成,我们是不是只要知道工厂有卖,买来再来用就好。
对于我们:我们只要知道买来的杯子怎么用,用来干嘛就好。
对于工厂:只需知道杯子如何生产制作,怎么销售就好,并不需要知道怎么用,以及用来干嘛。
这样就减少了每一个部份需要掌握的知识量。

6. 开闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

问题由来:

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

解决方案:

当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值