首页 > 代码库 > 从设计模式的设计原则感悟生活

从设计模式的设计原则感悟生活

设计模式中的很多思想还是很有意思的,刚毕业的时候接触设计模式感觉有点高深,坐而论道,感觉还是有些虚,平时做的小练习还能自己捣鼓一番,自己使用一下设计模式,然后大刀阔斧的改动代码,随心所欲,写完以后还能热乎劲上来高兴几天,时间长了就忘了很多的东西,只是感觉设计模式就是抽象,自己感觉也抽象。如果死磕着问自己,估计大脑里还是没什么印象了。到了工作中,又发现有些功能或者思想固然好,但是要在已有的项目中做一些改动,一下子又有点不知所措,时间长了,思想和行动就脱节了。工作中以面向对象为目标,实际中做着结构化的思路开发。 

设计模式的这几个原则自己是看了忘,忘了以后时间长了也忘了看了。如此恶性循环。 

看别人总结的原则描述很是详尽,但是看代码还是不够通俗,自己也来捣鼓一下,从自己的思路和理解来总结总结设计模式和工作生活的联系。

单一职责原则(Single Responsibility Principle)

定义:不要存在多于一个导致类变更的原因。即一个类只负责一项职责。

一种加班的原因 

在生活中我可以理解这里所说的职责就是每个人的工作职责或者技能,在公司,你就是员工,在具体的工作中,可能负责开发,测试,设计,需求等等。 

比如说开发,大体上可能有前端开发,后台开发,如果划分语言种类,可能有java开发,c++,php开发 

java开发可能还有可能是嵌入式,web等 

在工作中为什么分这么多的种类,而且很细,出发点也就是为了提供工作效率,优化工作,比如我们做项目,在项目A里面可能是设计java的swing开发,这个职责就和明确了,不会牵扯涉及到c++之类的内容,我们就可以设想,有一个很粗粒度的类做了工作的种类划分,一直细化到java 的swing开发,那么在这个项目的过程中,从原则上讲我只负责java swing开发的内容,在整个项目周期中我扮演了java开发工程师的swing开发部分职责。如果稍候有人找我做c#的webservice的联调测试,说这也是java swing工作师的职责,那么不好意思,这个不属于我的工作范围。可能这个时候就有领导来重新设定一个岗位是c#的webserive的开发工作,另外找一个人来做这个工作,如果人手不够,那么我就是身兼两职。显示工作中这种情况可能比较多:).可能一个人干着好几种工作,对于工作来说,实现这种完全的清晰划分还是有些困难,但是从个人成长来说是不错的。

补丁的噩梦

在系统中发生各种各样的问题是很常见的,可能对于一些比较紧急的问题,就需要提供补丁了,但是补丁可以解决问题,如果是高手就从根本上分析问题,找到问题的根源,从源头上解决,当然这种改动可能涉及的改动范围比较大,对于紧急补丁而言是不现实的,那么就头痛医头,脚疼医脚,先做一些不是很规范严谨的改动。等补丁上去了,之后各种各样的原因,变更就这么遗留下来了。等到之后的人来看的时候,又会抱怨代码写的太差,太不规范了,但是让他改,他还是没底,于是乎这种“懒惰”的保守思想保留了下来,直到第20个人进入了项目,发现一个方法几百几千个if-else,代码都不知道改从何该起。。。

这个也就说明了对于系统中出现的复杂校验,可以尽可能的提前做优化改进,保证功能的完整和单一,随着系统规模变大,模糊,不稳定的校验就会导致系统更严重的问题。

里氏替换原则(Liskov Substitution Principle)

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

定义2:所有引用基类的地方必须能透明地使用其子类的对象。

解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

可口可乐的全球统一口味

可口可乐在全球都奉行着统一的标准,使得在任何地方口味都基本一致。我们可以理解可口可乐的产品秘方是一个类,全球的可口可乐都给予它来作为生产的标准,用软件设计的角度来说,全球各地的可口可乐公司都是基于父类的产品标准,没有对可口可乐的口味有任何改动,如果基于不同的口味,可以根据情况定制,但经典的口味还是保留不变。

山寨的兴起和次品,劣品

说了可口可乐,来举个反例,比如说市面上苹果手机很畅销,国内的一些公司就开始复制了苹果的外观和基本的界面效果,有了所谓的High phone,但是苹果的核心的用户体验和产品性能这些特性厂商也没办法继承复制下来,因为苹果公司不可能给它这些东西。那他就自己来做,最后只要看起来界面主题和外观和苹果手机差不多就行了。从软件设计的角度来说,山寨产品继承了苹果手机的一些特性,但是有些核心特性没有的时候,子类就重写了父类的方法,这样使用效果和感官也大打折扣。

同样次品,劣品的道理也是类似,我就不多说了,你懂的。

依赖倒置原则(Dependence Inversion Principle)

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

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

买火车票

大家这些年买火车票比以前方便多了,以前基本都是通过车站的窗口或者黄牛来买,后来有了一些代理,买票就不用跑那么远了,前几年,铁道部开放了网上购买车票的方式,买票更方便了,现在还可以电话订票,通过其他的网站代理来买票。可以说买票的途径有很多种。可以理解买票时一个抽象的行为,我们只依赖于抽象,保证能买到票就行,至于通过哪种渠道,根据大家自己的情况。这样我们买票就依赖于抽象不依赖于具体的实体了。

发送邮件的邮件组

在工作中,邮件组还是很有工作效率的,比如公司有一个技术支持部门,设定为一个邮件组,在部门内部做了邮件的各种转发策略,保证华北区的客户问题发送到指定的人的邮箱中,如果支持的人有多个,那就都发送给他们,现在客户有一个问题,他就直接发送给这个技术支持的邮件组。他无须知道具体要发送给哪一个人,只要这个问题能够得到反馈和解释就可以了。这就是依赖倒置所要表达的中心思想。

接口隔离原则(Interface Segregation Principle)

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

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

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

医院买药的怪事 

在医院买药的时候,有时候会碰到这种情况,比如我需要吃一板药,可能大夫开药的时候会给你开一个大盒,或者一大包,理由就是药都是包好的,一次一包一大盒,不拆开卖的。我们可以理解一板药提供了一个短期的治疗效果,是一个简单接口,但是医院里面如果把一大盒药拆开,就没法分开卖了,这样就把这个问题的影响转移给了患者,让患者为这种情况买单。因为医院买药的接口是一个大接口,用户需要去实现那样他们不是很需要做的事情。

臃肿的机构和办事效率 

臃肿的机构和办事效率以前大家去各种机关办事,各种复杂的流程,各种盖章,各种签字,少一个都不行,只认章不认人。可能一个单位有很多的办事部门,因为以前的流程过于落后,可以理解为一个很大的接口,结果去办事的时候还要去做一些额外的盖章签字,准备各种材料,比如部门a已经提供了完整的个人信息材料,部门b还要从头再来,一个步骤都不能少,这样这个接口太大,办事的时间也拖的挺长。如果有一些小的接口,比如快捷的网上便民服务等等就是小的接口,这样效率也高很多。

迪米特法则(Law Of Demeter)

定义:一个对象应该对其他对象保持最少的了解。

解决方案:尽量降低类与类之间的耦合。

工作汇报

工作中我们经常要汇报工作的情况,但是从领导的角度而言,他更关心结果,不是过程,所以你在汇报工作的时候涉及太多的细节,会把自己引入一个无形的漩涡中,比如报告中提到了一个细节,和a部门同事a有什么关系,然后领到问你同事a的情况,问这个问题,然后又牵扯出部门b的另一个同事,这样解释了半天,发现还把领导弄糊涂了。迪米特法则就是最少知道原则,只要言简意赅的说明,那些实现细节等等就不需要过多的牵扯了。

微信中的留言功能

在微信的朋友圈中,如果你有好友a,b,c,但是好友a,b却互相不认识,那么你发的一些状态图片等,他们都能看到,他们给你回复的时候,朋友a看不到朋友b的留言,从根本上保证了用户的隐私,这也是微信中和微博中的一个不同点。微信的朋友圈更侧重个人的一些信息,不会暴露过多的信息。

开闭原则(Open Close Principle)

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

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

oracle 中的Long类型

如果大家用Oracle数据库,就会发现oracle已经在很早的版本中使用了long的数据类型,但是使用中碰到了一些问题,发现没有预想的那么好,于是产生了lob的数据类型,但是oracle的产品已经提供了很多完善的功能,为了后续的支持,不能把这部分变更彻底去掉,彻底去掉就不兼容低版本了。所以在后续的版本中明确提出舍弃了long类型,更是在一些操作中限制了它的使用,但是还是没有从根本上把它去除,开闭原则在这里就是oracle为了支持低版本的功能,对于扩展开放,引入了新的数据类型,但是对修改关闭,不能彻底的改动long类型。

领土问题

从这个角度最后来提一句,对于领土问题也是如此,对于扩展开放,如果能够摆正态度,有一个能够正常谈判的氛围,那么对于扩展是开放的,但是单方面的修改肯定是关闭的。

从设计模式的设计原则感悟生活