每个人都应该懂一点设计原则
发布日期:2021-10-20 03:26:37 浏览次数:4 分类:技术文章

本文共 3390 字,大约阅读时间需要 11 分钟。

PS:本人边学边记录,所以可能有欠缺有错误有不足之处,还望指导!

在学习设计模式之前我们有必要先了解一下一些设计原则.

其实设计原则也是从设计模式里来的,所以暂时不需要太理解,毕竟光看原则可能有时候理解不了.

讲设计原则,则不得不先提一下SOLID设计原则.

它的每个字母分别代表一个原则,接下来分别介绍一下.

单一职责原则(Single Responsibility Principle,SRP)

a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class)

简单来说就是:一个类应该只有一个职责(只有一个潜在的改变能影响这个类);

每一个引起类变化的原因就是一个职责,当类具有多职责时,应该把多余职责分离出去,分别创建类来完成,

否则这个类的耦合度会不断提升,不利于维护等.

比如某些所谓的多功能道具,集多少多少功能于一体,吹得很牛逼,结果呢?其中一个坏了,整个都坏了,全完蛋.

如果说我们的代码也这样,一个类又有Http请求又有IO操作的方法又封装了各种Util方法,背负各种职责,耦合度高得能吓死你,还怎么快乐地敲代码?

SRP的优点很明显:高内聚,低耦合,类结构逻辑清晰明了,提高了可读性,同时也易于维护

开闭原则(Open Closed Principle)

“software entities(classes, modules, functions, etc.) should be open for extension, but closed for modification.”

实体(类,模块..等)应该对扩展开放,对修改关闭.

也就是说实体可以做到不修改源代码就可以实现功能扩展.

比如我们实现了功能A,测试完后发布.后来我们需要增加功能,在不得已的情况下我们最好是对原有的代码功能实现扩展,而不是去修改原来的代码.

因为原来的代码经过了测试,而我们再次去修改很有可能破坏原来的代码,或者带来Bug,所以我们需要对修改关闭.

做到开闭原则可以做到稳定,可扩展

But,臣妾表示做不到啊!

里氏代换原则(Liskov Substitution Principle,LSP)

It states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).

简单来说就是:父类可以出现的地方,子类也可以出现,父类都可以被子类代替而无需改动.

其实这原则就是运用了继承,多态的特性,在很多设计模式中都有体现.

其实这个原则要求我们做的也很好理解,这么做就可以用一个方法符合所有T的类型,节省代码.

接口隔离原原则(Interface Segregation Principle,ISP)

(ISP) states that no client should be forced to depend on methods it does not use.

客户端不应该被强迫地依赖那些根本用不上的方法.

什么意思?
假设有个接口A,A有三个方法,而我们的类B需要其中的某一个,如果让B实现A那么B就会多依赖两个用不上的方法,这就违背了该原则.
另外这么做还有另外一个非常大的隐患,如果我们改变了A的其他两个方法,那么会影响到B.

在Java源码中我们可以找到很多接口都只有一个方法,比如:

public interface AutoCloseable {    void close() throws Exception;}public interface Comparable
{ int compareTo(T another);}

其实原因就在这个接口隔离原则上.

ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.

接口隔离原则优点:

  1. 让我们的程序解耦,更容易重构,改变,重新部署.

另外个人觉得接口隔离原则跟SRP其实挺类似,它也可以提高内聚,降低耦合,提升可读性~

依赖倒置原则(Dependency Inversion Principle)

the dependency inversion principle refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed), thus rendering high-level modules independent of the low-level module implementation details.

简单说就是:高级模块独立于低级模块的实现细节.

DIP指明了:

  1. 高级模块不应该依赖低级模块,它们都应该依赖于抽象.
  2. 抽象不应该依赖细节.细节应该依赖于抽象.

其他必须知道的原则

DRY

Don't repeat yourself.

不要重复自己,也许你听过很多次,但它绝不是复制黏贴那么简单.

优先使用组合,少用继承

在EffectiveJava 和HeadFirstDesignPattern里不止一次看到优先使用组合的建议.

继承的缺点可不少.

针对接口编程,而不是实现

这里的接口指interface抽象.

封装变化

把经常变化的代码封装起来,与不变的代码隔离开.

迪米特法则 (Law of Demeter Principle),也称为“最少知识原则(Principle of Least Knowledge)

wiki百科的解释挺好的,我就照搬过来了,如下:

  1. 每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元;
  2. 每个单元只能和它的朋友交谈:不能和陌生单元交谈;
  3. 只和自己直接的朋友交谈。

很多面向对象程序设计语言用"."表示对象的域的解析算符,因此得墨忒耳定律可以简单地陈述为“只使用一个.算符”。 因此,a.b.Method()违反了此定律,而a.Method()不违反此定律。

一个简单例子是,人可以命令一条狗行走(walk),但是不应该直接指挥狗的腿行走,应该由狗去指挥控制它的腿如何行走。

  • 优点

使得软件更好的可维护性与适应性。

因为对象较少依赖其它对象的内部结构,可以改变对象容器(container)而不用改变它的调用者(caller)。

总结

如果我们的目标是:Reliable,Scalable,Maintainable.,那么设计原则可以帮助我们实现,学习理解设计原则对编码大有裨益!~

理论需要与实际结合,多在写代码的时候考虑一下,对提高代码质量有很大的帮助~
好了,这次就写那么一点点,如有错误,欢迎批评指正,也欢迎交流!

推荐书籍

HeadFirstDesignPattern.

Effective Java.

参考/更多

另外欢迎关注:

我的微信公众号:

531570-c63cc064a8ebad2b.jpg
微信公众号

转载地址:https://blog.csdn.net/u014400934/article/details/101479042 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Hexo博客搭建之旅
下一篇:Android给apk签名那点事

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年03月24日 00时16分09秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

云栖社区 mysql_【直播结束,已更新回放】PG、MySQL到底哪个好?云栖说这次请来五位专家撕了一下-阿里云开发者社区... 2019-04-21
老男孩mysql 百度云_英语语录:除了你,没人能掌控你的幸福 2019-04-21
mysql驱动多次执行问题_Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动... 2019-04-21
mysql获取刚新增的数据库_如何取得刚插入数据库的数据的id mysql 2019-04-21
python将10到1递减_(Python)如何将3个递减列表合并成一个递减列表? 2019-04-21
python脚本怎么用来处理数据_长时间运行数据处理python脚本的程序结构 2019-04-21
python转成c 语言_将Python对象转换为C void类型 2019-04-21
resin mysql_Eclipse+resin+mysql 安装及环境配置 2019-04-21
redis的使用 Java_java中使用redis 2019-04-21
java 数组元素位置_Java – 在数组中获取元素位置 2019-04-21
c 泛型与java泛型_C ++和Java中的“泛型”类型之间有什么区别? 2019-04-21
java 返回实体对象_java 封装返回结果实体类 返回结果以及错误信息 2019-04-21
java web 防止sql注入攻击_JavaWeb防注入知识点(一) 2019-04-21
java ssm 异常分类_SSM项目常见的异常与处理提示(一) 2019-04-21
java定义矩形类_Java定义矩形类 2019-04-21
java变量怎么变常量_Java的常量与变量是什么?怎么学习呀? 2019-04-21
java开发招聘试题_客户化开发招聘试题-Java开发.doc 2019-04-21
java jdk win10 1335_win10下安装java jdk,tomcat 2019-04-21
java list二分查找_java中的ArrayList和LinkedList的二分查找速度比 | 学步园 2019-04-21
php中的变量名称用什么表示,PHP变量,方法,类等名称中的有效字符是什么? 2019-04-21