浅学设计模式之 几个设计原则(1.5/23)

单一职责原则

从字面意思来看,一个对象所做职责要单一。

就一个类而言,应该仅有一个引起它变化的原因

比如说我们写了一个类,在里面做SQL操作,又做了一些运算算法,这样的代码在需求来临时,我们都要更改这个类,有时候会对类的别的功能产生了影响,这其实很糟糕的,维护麻烦,复用不可能,灵活性极差。

如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化肯能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。

软件设计的许多内容,就是发现职责并把那些职责相互分离。
如果你能够想到多于一个动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离。

开放-封闭原则

开放-封闭原则,是说软件实体类(类、模块、函数等等)应该可以扩展,但是不可以修改

这个原则有两个特征:对于扩展是开放的,对于更改是封闭的。
这个设计原则保证 我们的程序设计在面对需求的改变时,保持了相对的稳定,从而使得系统可以再第一个版本以后稳定的推出后一个版本。

而我的上一篇设计模式的文章浅学设计模式之策略模式 (1/23)
策略模式在算法不断加入的时候,就只用做两件事情:

  1. 通过实现抽象策略接口去实现一个具体策略类
  2. 在Context上下文类中,通过判断去加一个多态

简直就是即插即拔,面向接口编程,理论上一个算法加入的时候,不影响其他算法的使用。而当这个算法加入完成之后对它的修改就应当关闭了。
但是实际上这个算法一加入的时候可能并不是真正完美的,以后有可能还是会进行一定的修改,所以说再最开始的设计时,就要多去想一些隔离的方法。

最简单的例子:
(1)在一个公司,有些员工因为一些原因老是迟到,如果通过申请特殊原因而允许迟到,别的员工就会不干了:凭什么允许他迟到,我也要迟到。
(2)其实对于公司来说,上班不是主要问题,最主要的是上班的那8个小时的时间,员工需要完成他们的任务。所以我们可以制定一些规则
(3)比如说弹性上班时间制度,早上班早下班,晚上班晚下班,或者一个月最多允许迟到三次,否则发钱,再或者迟到的人补时间就完事了。
(4)这就达成了对工作时间或业绩成效的修改关闭,而对时间制度扩展的开放。

开放-封闭原则的本质就是面对需求,对程序的改动是通过增加新代码进行的,而不是更改原有的代码。

依赖倒转原则

A.高层模块不应该依赖低层模块。两个都应该依赖抽象
B.抽象不应该依赖细节。细节应该依赖于抽象

这里有一个例子:
(1)比如我们是生产CPU的厂商,世界上生产CPU的本来就只有那么几家,AMD,Inter
(2)但是生产主板的却有n多家,华硕,神舟联想等等。
(3)在面对这么多主板,难道我们要分别对不同的主板去设计CPU吗?那显然是不行的,CPU的设计生产成本很高,而主板相对很低,那样的话,我们是重要的一方,却要跟着不太重要的主板去设计,那万一有一天,有客户不小心把主板弄坏了,但是CPU还没事,但是他换了别的主板,结果这个CPU也安装不进去了,那不是GG?再换成别的想想,不只是CPU,还有内存条、硬盘这些,我们想换掉其中一个的时候,会不会很麻烦?
(4)所以,我们要去定义好,不是我们根据主板设计CPU,而是主板提供好一致的接口,不管什么CPU还是主板,直接插上去就能用了,内存条硬盘也一样,即插即用。
(5)在这里面,高层模块是像CPU、内存条这样的高级硬件,而低层模块是指主板这样的。所有模块都抽象成在一个集合里面放东西,比如电脑在这里面就是抽象层,CPU、主板就是细节层!

至于依赖导致,我们先来看下下面的里氏替换原则。

里氏替换原则

具体的数学定义比较复杂,用大白话翻译就是 一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不到父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序行为都没什么变化。相当于爸爸可以当儿子,儿子可以当爸爸,不过这个比喻还是换成 哥哥可以当弟弟,弟弟可以当哥哥好一点。

里氏代换原则:子类型必须能够替换掉它们的父类型。

举个例子:鸟会飞,企鹅不会,在现实世界中,企鹅是鸟的一种,但是在里氏替换原则的编程环境下,企鹅不能代替鸟!所以它不能继承鸟类。
也正是有了这种原则,使得继承复用成为了可能,只有当子类可以替换掉父类,软件单位的功能不收到影响时,父类才能真正的被复用,而子类也能够在父类的基础上增加新的行为。

再举个例子:我们玩FPS游戏的时候会选择一个英雄,我们这一把想玩个半藏,下一把玩个根基,假如这个游戏一个号只能定义一个英雄,那岂不是我们想换个英雄,就要换个号,那累死!在这个时候“英雄”就是抽象父类,“半藏”,“源氏”就是子类,我们只需要让这俩兄弟去继承英雄,当我们在选择英雄的时候,“英雄”只需根据你选择来实例化一个“半藏”,或是“源氏”。
从替换角度上来说,“半藏”已经是被我当成“英雄”来用了,所以这就实现了子类替换了父类。而且,“半藏”和“源氏”拥有完全不同的技能,却依然能够依赖“英雄”,这就体现了这个原则的扩展良好性。
(PS:woc我这个例子举的真生动!!!)

这个时候再去看依赖倒转原则,高层模块和低层模块不应该互相依赖,而是他们都去依赖抽象。
之前也策略模式中也有提到过它有这个优点:策略模式下所有算法都是兄弟,他们都可以替换父类Strategy,而正是这个原则,也支撑了封闭-开放原则。也是典型的IOP面向接口编程原则。

迪米特法则

迪米特法则:如果两个类不必直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

有没有一点点像代理呢?
它的根本思想就是强调了类之间的松耦合。类之间的耦合越弱,越有利于复用。一个处在弱耦合的类被修改,不会对有关系的类造成波及。

这也是很基本的思想,使我们在开发的时候需要去注意的东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值