java基础巩固-宇宙第一AiYWM:为了维持生计,(设计模式之禅)六大原则阅读总结~整起
作者:互联网
首先很感谢设计模式之禅的作者先生把六大原则展示给我,让我有了学习的机会~感谢大佬(江湖拱手礼)
总的来说,能感觉到这六个原则有一句话总结就是“开闭原则相当于抽象,而其他的五个原则:如单一职责原则、迪米特法则、里氏替换、依赖倒置、接口隔离等都是相当于开闭原则这个抽象的具体化”
应该怎么理解这一句话呢,从以下几个角度出发可能对自己这个java_green_bird友好一点。
- 什么叫抽象?什么又叫具体化呢?
- 我个人理解的话,咱们在java中谈类和对象关系的时候,也会说对象相当于类这个抽象东东的具体化。再大白话一点,我觉得就是:
- 我是一个建筑男,有了图纸,我按照图纸造房造桥,这个图纸上画的房和桥就叫做抽象的 房和桥,实际盖在地面上的房子、架在河上的桥就叫做具体化后的实物(有的时候也叫做一种实现,这个实现的意思和咱们汉语词典里面的差不懂,不懂的可以去翻翻找找)
- 我是一个机械男,有了图纸,我按照图纸上画的螺纹螺母造机器…图纸上的…实际中的…
- 我是一个…
- …
- 我个人理解的话,咱们在java中谈类和对象关系的时候,也会说对象相当于类这个抽象东东的具体化。再大白话一点,我觉得就是:
我觉得遇到晦涩难懂的概念的时候,用自己熟悉的自然语言去解释他,让自己能够充分理解是一个不错的方法。
回到六个原则中来,为什么说开闭原则是抽象的,你抽象的相当于一个老大(不算一个100%的纯掌握全部权利的老大,最起码也是掌握的大部分权利的老大身边的副手吧~比如戴着眼镜留着蘑菇头的翻译官),我具体化的东西都得按你这个来
这是因为呀,咱们平时做项目或者写代码的时候,经常会碰到我已经写好了代码,或者已上线或者已经…(反正就是完成了,自己感觉已经做完了),但是boss又让我去改去修去补(糟老头子坏得很,不讲武德),一次两次小修小补还行,你要碰到那种动不动就要拆我写好的一堆代码,给你连根快拔起那种。
- 你不慌?,如果你是个面向对象的战士,你写了一大堆继承,写了一大堆实现,让你改接口改父类
- 来,给我某个类某个接口中增加个抽象方法,已经实现了这个接口的类是不是都要在把你新增加的这个抽象方法给覆盖重写一下(这是接口或者抽象类的规矩,你继承或者实现了人家就得把人家肚子里的抽象方法都覆盖重写)—这可以算是理论上的破坏
- 来,给我某个父类中某个方法里面增加几句打印代码,那这个父类手底下的子类不是全部都遭殃了嘛(因为这也是父类的规矩,子类无条件拥有父类的所有方法),这就相当于造成了理论上加实际上的破坏。举两个例子,你见过会飞会叫的铁鸭子嘛,你见过会打子弹的木枪嘛(Head First设计模式和设计模式之禅中有这两个例子),造成这种不切合实际的后果就是因为咱们要是胡乱扩充父类里面的方法,就会让有的子类中的功能不切合实际。
自己当时看的电子版截的屏做的笔记~记录在案。如下:
所以呢,尽量别去修改(这不就对修改关闭了门),可以封装一个接口、一个类、一个方法作为中介,然后可以结合封装、继承、多态等等,然后去实现怎么要增强的功能。(原来我没有,我找了个中介,那这个中介可不可以算作是我的一种扩展)
- 平时咱们也可以通过类文件替换的方式可以修正已经运行的软件产品系统中的一些缺陷或者给已运行的软件系统增加一个新功能(比如有自动更新功能,则可以下载一个.class文件直接覆盖原有的class),但是一定要注意别出现会飞的木头鸭子和会打子弹的木枪
***当然,要特别写给自己的一句话就是,那么把这六种原则反复看,但是其中的尺度其实真的很难把握,就比如
- 怎么扩展?
- 怎么才算不修改?
- 再像单一职责下的什么叫单一职责?
- 怎样划分或者说以什么样的尺度去划分职责?
- 迪米特法则要求类之间解耦(感觉01二进制那种才算是很大程度的解耦)?
就像书中人家作者说的一样,具体问题具体分析(这句话很有道理呀,咱们的前辈们很多都说过相关的话:一切从实际出发、理论联系实际…),咱们唯一能做的就是,多学学,学了肯定有效果,大小与多少的关系罢了,但你不动你永远掌握不了*,不是嘛**
下来就到五个具体的原则了,他们彼此之间有很大的联系,原则中体现的一些想法都是很有联系很相近的。
下面就分享一下自己看了书之后的一些感触吧。
1.单一职责原则
-
接口一定要做到职责比较单一
-
记录书中的新话:咱们一般做项目,肯定要接触到用户、机构、角色管理这些模块,基本上使用的都是RBAC模型(Role-Based Access Control,基于角色的访问控制,通过分配和取消角色来完成用户权限的授予和取消,使动作主体(用户)和资源的行为(权限)分离)
左边就是咱们把所有的写到一个接口中,右边是按照单一职责优化过的良好的代码。
-
类尽量这个类只有一个原因能够引起类的变化
-
除了操作资源类的和其他功能的两种要分开
-
还有咱们的单一职责在方法上面的应用(虽然就来一个方法很爽,给方法中放很多不同类型的形式参数来实现不同的功能逻辑等),咱们项目中用方法实现了几个功能:
- 比如changeVipUserName(…),修改分店VIP用户的姓名
- changVioUserHomeAddress(…),修改分店VIP用户的住址
- …
尽量让每个方法的职责也明确一点,把他们分开。
但是还是那句话,过犹不及,别分的粒度太细太细太细了。
2.接口隔离原则
-
接口隔离原则,可以举个例子就是:小胡的老婆闫sir(YWM)说,老胡,这个月你的工资咋还没上账呢,我的余额还没增加呀。小胡说,好,保证解决任务长官。过了10秒钟他老婆的账上立马多了些钱。**这种不讲条件、立刻完成任务的行为就是高内聚的表现。**具体到接口隔离原则中就是,尽量少向外公布一些public方法,这样可以降低变更的风险。
-
接口隔离原则的作用我觉得也是和单一职责差不多,都是想着把一个大的臃肿的接口分为多个功能比较纯的比较明确的小接口。不要让接口中太臃肿了。但是他俩审视的出发点还是有点区别的
- 单一职责就像咱们上面说的,按照业务逻辑上的所谓的职责进行划分(但是职责确实很难度量,目前能想起来的就是上面的操作资源类的和其他功能的两种要分开,欢迎评论补充)。
- 而接口隔离原则要求接口内的方法尽量少
-
但是满足接口隔离职责之前肯定是要先满足单一职责原则的
-
另外除了按照咱们的功能方法或者职责角度(单一职责或者接口隔离)去考虑解耦类、接口、方法等,当某一个方法(假设咱们整个类或者接口中有多个方法时)很明显有拖低咱们代码执行效率的风险或者说他不太安全,那咱们也可以把这个方法单独放出来(放到一个中介接口或者类中)
3.依赖倒置原则
依赖倒置原则我觉的人家书里提到的几条规矩还是挺好的,咱们平时写代码的时候,碰到书里面的不让干的啥啥啥…,咱就尽量规避一下类似冒险行为。碰到书里的尽量让干啥干啥干啥,咱们就多按照人家的原则,优化优化呗。
- 假如闫老板,开了不同的分店卖不同的货物,下面的类图可能能体现出依赖倒置原则(虽然自己感觉和其他几个原则也有联系,但是就准备以后有相似的需求,就准备这样来组织代码结构)
- 按照书中的知识安利一个小概念:
- 表面类型指的是抽象接口
- 接口的子实现类叫做实际类型
- 按照书中的知识安利一个小概念:
4.迪米特法则
迪米特法则我觉的主要有以下几个点:
- 尽量不要把类套的太多太深,啥意思呢,就是咱程序中别有一个类套一个类再套一个类再套…一时套类一时爽。虽然要解耦和时咱们不知道怎样才算彻底解耦和,但是如果一个类要跳转两次以上才能访问到另一个类(此时由于跳转次数越多系统越复杂,后期维护起来就越困难),就不太合适了,就得考虑一下对于接口、类、方法等的重构一下了。
- 但是还是那句话,不遵循原则不合适,但是过犹不及(太过了也不行哦),要具体问题具体分析。人家想杠你就说,我不按你这样来我的项目照样上线运行了,完好无损,照样挣钱着呢…确实,先手动点个赞,毕竟实际中要考虑很多因素呀,成本、时间等。
- 另外一个点就是尽量在写类中的方法们时,考虑一下是否可以把想写的public改为private、defaulted、protected等。因为如果咱们用public时,别人就有可能有意无意之间就对咱们的类进行了修改,修坏了或者改变了咱们类原本的功能意图怎么办?
- 除了缩小权限修饰符之外,看能不能加上final等关键字啥的,更加安全。
5.里氏替换原则
- 里氏替换我感觉,就是提醒咱们,父类出现的地方以及所在的位置,换个这个父类的子类顶到同样的位置,功能照样照常运行,不会发生异常。
- 然后有一点就是有的时候父类可以和子类跨包进行方法重载(借用作者的一句话就是:谁说没在一个类中就不能进行方法的重载)
- 然后当发生了方法重载后,子类的形参(官话叫前置条件)要比父类的形参范围大(就比如说你父类的形参是HashMap hashMap,我子类的形参就要是Map;子类的形参要是List, 父类的形参就是ArrayList等),这样才能保证代码的正确
-
上面举的例子中Map、HashMap、List、ArrayList的关系,可以参照下面的图
-
其实也好理解,就是一般子类咱们有的时候就复用父类中的全部东西,或者子类会再增加一些自己独有的方法呀属性呀等等。所以整体上来看,子类是比父类“大或者叫宽”的
- 这种情况下,当子类的输入参数的类型的范围扩大了话,有的时候子类会代替父类被传递到调用者中(那么子类重载的同名方法就不会被执行)。如果这个时候咱们想让子类中的方法执行,就必须覆盖重写父类的方法。(这里书上举了个例子,给我当时搞混了半天!!!),当时手机上截屏做了笔记,记录如下:
- 这种情况下,当子类的输入参数的类型的范围扩大了话,有的时候子类会代替父类被传递到调用者中(那么子类重载的同名方法就不会被执行)。如果这个时候咱们想让子类中的方法执行,就必须覆盖重写父类的方法。(这里书上举了个例子,给我当时搞混了半天!!!),当时手机上截屏做了笔记,记录如下:
-
标签:设计模式,java,原则,之禅,子类,接口,父类,方法,咱们 来源: https://blog.csdn.net/m0_52436398/article/details/122474901