1. 聚能聊>
  2. 话题详情

聊聊设计模式,你必须知道的六大设计原则

接着上一个话题:聊聊设计模式,什么是设计模式?你知道多少?,我们今天来聊一聊设计模式的六大设计原则。
六大设计原则

1、单一职责原则(Single Responsibility Principle - SRP)
定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责,只有一个引起它变化的原因。
问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。

2、开放封闭原则(Open Closed Principle - OCP)
定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。
解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

3、里氏替换原则(Liskov Substitution Principle - LSP)
这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的。
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
定义2:所有引用基类的地方必须能透明地使用其子类的对象。
问题由来:有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

4、迪米特法则(最少知道原则)(Demeter Principle)(Least Knowledge Principle - LKP)
最少知识原则又叫迪米特法则,最早是在1987年由美国Northeastern University的Ian Holland提出。
核心思想是:低耦合、高内聚
一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

5、接口隔离原则(Interface Segregation Principle - ISP)
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

6、依赖倒置原则(Dependence Inversion Principle - DIP)
依赖倒置原则的核心思想是面向接口编程,不应该面向实现类编程。
在实际编程中,要做到下面3点:

低层模块尽量都要有抽象类或接口,或者两者都有。
变量的声明类型尽量是抽象类或接口。
使用继承时遵循里氏替换原则。

那么对于这六大设计原则:
1、你有没有不同的见解呢?

2、它们的排位有先后吗?你觉得哪个应该在第一位?

3、你还知道其它的设计原则吗?

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。

参与话题

奖品区域 活动规则 已 结束

  • 奖品一

    阿里云代金券 x 5

  • 奖品二

    手机话费 x 3

  • 奖品三

    品牌U盘 x 1

12个回答

1

海阔天空yy 已获得手机话费 复制链接去分享

1、你有没有不同的见解呢?
没有什么不同吧,现在设计基本都是这样的。
2、它们的排位有先后吗?你觉得哪个应该在第一位?
单一职责原则,应该放第一位,因为这是规划代码的基础,这步如果做好了,代码才会比较清晰,
当然其它的也很重要
3、你还知道其它的设计原则吗?
java的设计模式大体上分为三大类
创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
这个到某些时候肯定是要有取舍的,可能每个人想法不一样吧,像我的话,如果遇到这种情况的话, 一般是以性能为先的,
因为写程序的目的不就是为了实现功能,性能要好。那种方面能提高性能就用那种。
比如数据库方面如果 字段允许适当冗余,以提高查询性能,肯定要用冗余。
很多时候规则是死的,人是活的。

1

shawn.ss 已获得阿里云代金券 复制链接去分享

求代金券哈~~~
1、你有没有不同的见解呢?
设计模式是前人的经验总结,防止软件工程因为过度复杂而腐坏,变得无法维护,核心概念是用一些基本套路来管理复杂度

2、它们的排位有先后吗?你觉得哪个应该在第一位?
不同方面的软件设计需要不同的策略,六个原则是设计的核心思想,例如在做模块设计的时候,会优先考虑高内聚,低耦合,在设计对外接口的时候,会考虑最小知道原则,其次还会考虑依赖模块的层次,采用依赖反转来确保不出现循环依赖,依赖的顺序单一。不同场景使用不同原则,并无固定排位。

3、你还知道其它的设计原则吗?
例如,
0,1,无穷原则,一个类的实例只可能有三种情况,没有,一个或者无穷多个,这个原则可以保证不会出现因为数量限制造成的软件扩展困难。
接口依赖原则,如果实现的方案不确定,应抽象出具体实现的抽象接口,将依赖建立与此接口之上,而非某个特定实现类,此原则保证了切换底层实现时,不会对上层的结构造成影响,从而隔离变更,牵一发动全身的设计并非好设计。

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
完全符合这个概念和绝对纯净物类似,可望而不可及,但优雅有活力的设计必定是在上述原则的基础上设计的。原则也不是教条,是一个思考和判断的方向和思路。使用原则肯定会和各种事实条件冲突,最终从中找到一条最合适的路,做一个最合适的设计才是程序员的本领所在。
题目中的例子就是违背单一职责原则的设计,因为一个数据表冗余其他表的信息,会造成这个表的职责并不单一,维护这个表的时候也需要考虑维护表内信息和冗余信息两个方面,但是有利有弊,这么做之后可以减少连表,使查询性能提高,而且查询的业务更需要优化的情况下,这个设计时好的设计。
此外还有接口隔离原则原则,如果严格遵守,一些配置项只在特殊实现情况下有意义,那么对外提供时,应该拆分成不带配置项的接口,再用带配置项的接口扩展前面的接口,只有特殊的实现类会实现后面这个接口,但这种设计,会使得软件编码的量增加很多,那么很多情况下就是只设计一个接口,特殊配置项的方法,大部分实现类只会提供空方法,无任何实际作用,而特殊类才需要提供此接口的实现。
没有最好的软件设计,只有最适合的软件设计,有一利必有一弊,最终权衡利弊,合理设计要好过教条主义,生搬硬套

1

北方的郎 已获得阿里云代金券 复制链接去分享

1、你有没有不同的见解呢?
没啥不同见解,这6个都几乎变成业界共识了。

2、它们的排位有先后吗?你觉得哪个应该在第一位?
我排的话SRP-〉OCP-〉LKP 其他随意。

3、你还知道其它的设计原则吗?
基本上就是那本书的二十来个。

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
关键是看项目规模,做架构和代码框架的时候要同时避免设计/架构不足和过度设计/架构。

1

cjsoldier 已获得阿里云代金券 复制链接去分享

1、你有没有不同的见解呢?
开闭原则说的太抽象。对扩展开放,对修改关闭。我的理解就是多弄些配置文件,以后只需要修改配置文件就行了。
一般认为配置文件不属于代码。
迪米特法则说的跟我了解的不太一样。该法则说的是避免直接通信。如果A要B通信,不要直接通信,而是通过C来通信。

2、它们的排位有先后吗?你觉得哪个应该在第一位?
理论上是没有的。但是迪米特法则我觉得用的机会比较少。应该放在最后。
单一职责放在第一位我没意见。

3、你还知道其它的设计原则吗?
合成复用原则。复用时要尽量使用组合/聚合关系(关联关系),少用继承。
关于这七个原则我编了一句口诀:单开李义揭合缔。
单独把李义踢出团队,结果东窗事发了。这是少年包青天2《义薄云天》里的故事。

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?
比如接口隔离原则,如果太小了,就会有一堆的接口,很烦人的。
单一职责也是。我觉得能做到方法级别的单一职责就相当不错了。
至于类级别的单一职责视情况而定,怎么样才算单一职责?一个类只有一个方法才算单一职责吗?
说实话设计模式真的很复杂啊。除非特别熟,否则我都不敢乱用。比如那个迪米特法则,弄不好反而把自己给弄糊涂了。
我感觉除非特别熟练,否则还是尽量简单点好。

0

小可同学 已获得品牌U盘 复制链接去分享

1、你有没有不同的见解呢?
没有,前人总结的精华!我能理解并用用到工作中就是算是最大的回报了,我觉得。

2、它们的排位有先后吗?你觉得哪个应该在第一位?
没有,从成果的角度来说,这几个设计模式都是很好的节约时间的解决方案!没有什么前后之分,只有在不同的地方体现不同的价值,不分排名先后。

3、你还知道其它的设计原则吗?
这个知道很多,之前看过一本蓝皮的书写的很生动形象,那本书是《深入浅出设计模式》。我还写了个笔记总结了一下,因为之前学习的事Java所以用的Java语言。
地址在这里,我觉得这些设计模式适用于各个语言。是很好的工具思想。
http://blog.csdn.net/jack__chiang/article/details/70208886

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
首先我做的时候,比如在创建类的时候,我会看看那五种创建型模式那个是自己需要的!比如不需要每次都创建个对象!每次我都用一个对象!每次我都产一种类型的对象等!还有适配器模式,装饰者模式,这类结构型的!在固定结构中使用!
当然没有万能的设计模式,也没有万能的人!所有的原因当然我们可以给它划分成小问题,用不同的设计模式完成,在把解决的小问题汇总不就是最终的答案!就像Map先汇集成小块在 Reduse到一起一样的思想!
对于在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致:
当然第一点这个字段不能频繁修改,第二点这个字段长度要得到控制不能用可变长度!这样很容易影响速度,如果这个字段是索引的话更因该如此。

楼主定制U盘好漂亮!赏一个可好^-^

0

浮生递归 已获得阿里云代金券 复制链接去分享

大佬,打赏个U盘呗,缺个U盘做系统启动盘~8G的完美,不浪费~

1、你有没有不同的见解呢?
没有,这是前人精炼出来的东西,我们这种小菜鸟怎么可能跟他们叫板,能学过来都很好了。

2、它们的排位有先后吗?你觉得哪个应该在第一位?
目前的排位没毛病,单一职责原则在第一位很好。这点确实也非常重要。

3、你还知道其它的设计原则吗?
有这6个经典原则就够了吧,像你上次发的那23个模式,数量太多记都记不住,还怎么应用……

4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
我觉得大部分符合就不错咯。大部分程序在经历了整个变态的开发过程后,都是破旧不堪,符不符合规范都很难说,更不用说这么多原则。反正我在实际工作上,看别人的程序代码时,总是一堆问题。据说同事接受另一个同事的项目,也是一大堆BUG。有BUG还怎么运行呢?每次程序运行时,开发者都在电脑前手动操作,所以每次客户用那软件都要他驻场……

0

aoteman675 已获得手机话费 复制链接去分享

1、你有没有不同的见解呢?
已经表述得通俗易懂了
2、它们的排位有先后吗?你觉得哪个应该在第一位?
SRP,因为SRP在开发中用得最多,几乎每个功能类都会使用得吧。其次是 OCP在项目迭代升级时用,整个项目迭代维护周期都在用 OCP。
3、你还知道其它的设计原则吗?
是不是还有个组合/聚合复用原则?就是用组合和聚合达到复用效果。
4、真的有完全符合以上原则的设计吗?也就是说你在依照以上原则进行设计的时候有没有遇到不能两全的难题,是怎么取舍的呢?在设计方面有什么心得跟大家分享一下!就比如:在设计数据库表的时候,字段允许适当冗余,以提高查询性能,但必须考虑数据一致。
项目也有大小,团队能力也有高低,不可能项目的架构设计完全包含以上的六中原则和24种设计模式,只要项目框架超前设计和框架性能爆表就行了。
适当使用设计模式,项目转维的时候轻松一点,技术人员水平也有限。
我觉得用好SRP、OCP、LSP就行了。其他的用不好就是冗余设计、冗余代码。

0

沙漠的热情 已获得手机话费 复制链接去分享

1、你有没有不同的见解呢?
我没什么不同的见解,他人说设计模式好,咱人云亦云也说设计模式确实有用。

2、它们的排位有先后吗?你觉得哪个应该在第一位?
最好不分先后,非要一个第一的话,您随意!

3、你还知道其它的设计原则
看金庸倚天屠龙记,记得张无忌学太极拳,是先学再忘。

4、真的有完全符合以上原则的设计吗?
有说法叫“忘掉你学的MBA”,你亦可说去他的林林总总的设计模式,还可以有效率优先原则。

0

1538020126142428 复制链接去分享

域名过户在哪里?

微wx笑 回复

域名控制台

评论
0

求道 复制链接去分享

都很重要 最基础的准则

0

风清扬2 复制链接去分享

看了一遍学到了很多东西 收藏了

0

1023120583069697 复制链接去分享

不懂你们这是干嘛的,但是我想学习一下

4169
浏览
0
收藏
邀请他人互动
关注
80
粉丝
98
话题
35

简介:

无知人生,记录点滴。 不积跬步,无以至千里;不积小流,无以成江海…… 微信订阅号:微wx笑, 个人站点:http://www.wei-xiao.top/, CSDN博客:http://blog.csdn.net/testcs_dn

结合大数据能力帮助电商企业快速搭建平台、应对业务高并发,剖析秒杀、视频直播等场景

为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...