设计模式之路
一个类就能解决的事情,非得拆出四五个类,还得处理类之间的关系,这是在炫技,没有实际用处,这就是我当初的想法
确实,如果代码少或者系统业务不复杂的情况下,怎么写都可以,实现了功能就好了,但在后期维护上如果没有一个好的设计,那就是在堆屎山。写的人爽,维护的人骂娘
内心os:我目前在维护的这个系统真是让我苦不堪言,就是因为当初没有一个好的设计,现在想改也改不了,业务量巨大,不想吐槽了,任务就是保证系统正常运行就好
什么情况下不用设计模式
1、没学过,或者学过不会用
2、需求简单,用设计模式确实没必要
3、工期紧,还讲究什么模式,先实现功能吧
目录
- 为什么要学设计模式
- 什么是设计模式
- 看看你在第几层
- 如何学明白设计模式
- 去哪学?怎么学?
- 设计模式的六大原则
- 创建型模式
- 结构型模式
- 行为型模式
- 总结
为什么要学设计模式
在《重学Java设计模式》中有一段说的特别形象
就像火车加一节车厢不需要改动整列火车 插线板可以支持随时插入各种功能的插头 签字笔没墨水了可以更换笔芯 总之满足基本原则:做出一个可扩展、易维护、好管理的工程代码
参照spring与jdk的源码,为什么debug会经常跟丢?为什么要用工厂来返回对象,不去直接new?为什么一个方法就一句话,甚至空实现?开发者们在这么庞大的工程面前,如果没有一个好的设计,就和盖楼只会砖头堆砖头一样,代码会越来越糟糕。最后总结下面5点
- 面试。不解释了很大几率会问到,索性都是背八股,不如系统性的学一遍
- 不在束缚于语言。有好的设计能力才是研发人员的价值所在
- 拒绝CRUD第二步。不当一辈子码农
- 拒绝代码屎山。只有真正遇到过的才理解这种痛
- 阅读源码更从容。源码其实也就是设计模式+反射
什么是设计模式
设计模式英文名叫Design pattern,用来解决软件设计中普遍存在的各种问题的解决方案
不局限于代码,就算是一种设计模式,在不同场景中也会有不同的实现方式
看看你在第几层
第一层:没听过什么是设计模式
第二层:写了很多代码,也用到了设计模式,但自己不知道
第三层:学过设计模式,发现自己已经在使用了,并且发现了一些新的设计模式
第四层:阅读别人源码和框架,发现设计模式的精妙与带来的好处
第五层:写代码没有意识到自己使用了设计模式,但能熟练的写出来
如何学明白设计模式
学习每个设计模式,都应该思考
1、该模式的使用场景
2、该模式类(角色)之间的关系
3、这个设计模式是哪里好?哪里值得学?哪里会用它?
4、在框架中,源码中哪里得到了体现?我从中能学到什么?
去哪学?
我在b站看两位老师的视频学习,地址附上,另外自己买了一本《重学Java设计模式》,因为上本《算法》有点后悔,实在是难啃。这次买个能读下去的,目前看下来这本书写的确实比较浅,不通透,比如工厂模式就讲了两种。其他模式讲的穿插了大量业务伪代码,导致核心的设计模式不好体现,在抽象工厂模式中还穿插了代理模式,能把一个模式先讲明白了再说吧。总之这本书我不是很推荐
看完视频就刷博客,重要的是要尽量搞懂一个设计模式,然后在学下一个
有两个博客写的也不错,链接也附上
尚硅谷Java设计模式(图解+框架源码剖析)_哔哩哔哩_bilibili
Java设计模式-Mr.high_哔哩哔哩_bilibili
永不磨灭的设计模式(有这一篇真够了,拒绝标题党)_ShuSheng007的程序人生-CSDN博客
怎么学?
光看不练学不会,多敲多练多找源码体现,不得不说,比数据结构学起来可太轻松了,看看spring源码中哪里用到了,看人家大佬是如何实践落地的,自己尝试在业务中加以应用
重要的是不对某一设计模式钻牛角尖,它为什么不按照官方的这几大角色来实现,这怎么少一种角色?设计模式本身就是一种思想,不要拘泥于实现
学完或许懵,因为需要大量实践去丰富所学到的理论,要相信1w小时定律
设计模式的六大原则
这 6 种设计原则是软件设计模式必须尽量遵循的原则,是设计模式的基础。(有的也说7种,都可以吧,不要吹毛求疵,放弃本质)实际上,这些原则的目的只有一个:降低对象之间的耦合,增加程序的可复用性、可扩展性和可维护性。也是所有设计模式共同的优点
设计原则 | 归纳 | 目的 |
---|---|---|
开闭原则 | 对扩展开放,对修改关闭 | 好维护 |
单一职责 | 一个类只干一件事,实现类要单一 | 提升可读性 |
里氏替换 | 不要重写父类的方法 | 防止继承泛滥 |
迪米特法则 | 最少知道,对象之间少建立联系 | 解耦 |
接口隔离 | 一个接口只干一件事,接口要精简单一 | 高内聚,低耦合 |
依赖倒置 | 高层不应该依赖低层,要面向接口编程 | 利于结构升级 |
单一职责(常用)
一个类应该只负责一个功能。比如userDAO只负责用户的相关功能
开闭原则(常用)
对扩展开放,对修改关闭。我们在添加功能时不应该修改源代码,而是通过扩展类的方式增加功能
迪米特法则(常用)
也叫最少知道原则,指一个对象对其他类来说知道的越少越好,类之间不要有过多的耦合关系,陌生类不要作为局部变量出现。被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息。
里氏替换
所有引用父类的地方必须能透明地使用其子类的对象。也就是说在子类中尽量不要重写和重载父类的方法。
接口隔离
尽可能的拆分接口。一个类对另一个类的依赖应该建立在最小的接口上。
依赖倒置
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
设计模式种类
分为创建型(5种)、结构型(7种)、行为型模式(11种)
设计模式 | 归纳 | 案例 |
---|---|---|
单例模式 | 世界上没有两片完全相同的树叶 | CEO |
原型模式 | 72变 | 克隆 |
建造者模式 | 属性自由搭配 | 装修 |
代理模式 | 自身能力不足找别人帮忙 | 代言人 |
外观模式 | 统一接口封装 | 前台 |
装饰器模式 | 灵活,套娃 | 俄罗斯套娃 |
享元模式 | 共享资源 | 连接池及各种池 |
组合模式 | 整体-部分 | 组织架构 |
适配器模式 | 兼容转换 | 电源适配器 |
桥接模式 | 两个维度分离开 | 桥 |
模板模式 | 定义一套模板,根据需要实现模板中的操作 | 写周报 |
策略模式 | 用户进行选择方案 | 出行方式 |
责任链模式 | 流水线传送带,各级互不关联 | 流水线,审批流 |
迭代器模式 | 数据访问方式 | 遍历集合 |
命令模式 | 运筹帷幄之中,决胜千里之外 | 遥控器 |
状态模式 | 根据不同的状态做出不同的行为 | 线程生命周期 |
备忘录模式 | 失足不成千古恨,人生还能重来 | 游戏存档 |
中介者模式 | 我只和你一人联系 | 房屋中介 |
解释器模式 | 实现特定语法解析 | 编译器,密码本 |
观察者模式 | 有新消息通知我 | 公众号 |
访问者模式 | 横看成岭侧成峰,远近高低各不同 | 压榨打工人 |
工厂模式 | 封装细节,生产更高效 | 工厂 |
创建型模式
关心么样去创建对象,然后与使用者分离
1、单例模式
指某个类中只存在一个对象实例。sprng中bean默认都是单例模式
空降地址:柠檬大师:看完就明白之单例模式
2、原型模式(了解)
clone()方法,spring的bean中也提供了prototype的常见方式
空降地址:柠檬大师:看完就明白之原型模式
3、工厂模式(包含工厂方法和抽象工厂,简单工厂不属于GOF的23种之内)
又分为简单工厂模式、工厂方法模式,抽象工厂模式。
在创建对象时不会暴露具体细节,而是通过一个接口来创建对象
空降地址:柠檬大师:看完就明白之工厂模式
4、建造者模式(了解)
隐藏了复杂对象的创建过程,将一个复杂对象(属性多)赋值的问题
比如lombok中的@Builder注解
空降地址:柠檬大师:看完就明白之建造者模式
结构型模式
如何将类或对象按某种布局组成更大的结构
5、适配器模式
指多个对象类型转为一个对象类型然后去统一实现方法,比如常见的类包含adapter字样的,都用到了适配器模式,其中MVC最为经典,可以空降看分析
空降地址:柠檬大师:看完就明白的适配器模式
6、桥接模式(了解)
应对两个及以上独立变化的维度,解决类爆炸的问题
空降地址:柠檬大师:看完就明白的桥接模式
7、装饰者模式
又称套娃模式,在不改变源码的情况下,动态的给对象添加一些职责和功能
空降地址:柠檬大师:看完就明白的装饰者模式
8、外观模式(了解)
这也能叫设计模式?存在即合理,外观模式的思想确实频率用的很高。它对外提供统一的交互接口,隐藏内部的子系统调用。相当于一个总开关的角色
空降地址:柠檬大师:看完就明白的外观模式
9、组合模式(了解)
用来解决部分—整体的关系的一种设计模式,当程序结构中出现了类似树(部分—整体)一样的层级结构时,可以考虑使用组合模式
空降地址:柠檬大师:看完就明白的组合模式
10、代理模式
帮助别人干它的事情,除此之外还能另外的帮它作更多事情,比如常见的AOP切面编程,就很好的用到了代理模式
空降地址:柠檬大师:看完就明白的代理模式
11、享元模式(了解)
就是各类池,比如数据库连接池,缓冲池,常量池等,共同的目标就是减少内存的使用
空降地址:柠檬大师:看完就明白的享元模式
行为型模式
描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。是一个大的模式,包含11种模式
12、命令模式
家里的遥控器可以进行发布各种命令,而我不需要知道它是怎么做到的,我只关心它可以给我完成对应的功能,将请求者(me)与执行者(遥控程序)解耦
空降地址:柠檬大师:看完就明白的命令模式
13、模(mu)板模式(了解)
日程写的周报千篇一律,只需要每周改吧改吧内容就好了,格式基本都不会变,这种场景下适合使用模板模式
空降地址:柠檬大师:看完就明白的模板模式
14、访问者模式(了解)
我愿称为没什么用的模式,不大能想到平时在什么地方使用,实战中在积累经验吧
空降地址:柠檬大师:看完也不明白的访问者模式
15、备忘录模式(了解)
像平时的游戏存档类似,它可以记录对象在某一时刻的状态,当需要的时候可以快速回到当时的状态
空降地址:看完就明白的备忘录模式)
16、迭代器模式(了解)
一般我们会用到Java类提供的Iterator来进行遍历,其中的思想就是迭代器的思想
空降地址:看完就明白的迭代器模式
17、观察者模式
用过的一些监听器类,会监听你某个动作执行后,调用相关的一些行为。类似的,当一个对象状态发生改变时,依赖它的对象会得到通知并做出相应的行为
空降地址:看完就明白的观察者模式
18、解释器模式(了解)
为编译器提供的一个设计模式,一般情况下用不到,用到的也不是一般人,涉及到了句子,文法,语法树等
空降地址:看完就明白的解释器模式
19、中介者模式(了解)
中介这个词应该很熟,买房需要中介,假期打工需要中介等等,你只需要和中介一人联系,剩下的中介去干,当然其他人也只需要联系中介,这样就进行了解耦
空降地址:看完就明白的中介者模式
20、状态模式
最实用的地方就是用来消除if-else了,当一个对象状态改变的时候,其内部行为也随之改变
空降地址:看完就明白的状态模式
21、策略模式
是一个简单又开发常用的设计模式,当存在一题多解的情况时,可以使用策略模式使程序更加灵活
空降地址:看完就明白的策略模式
22、责任链模式
将一个对象传给下一个对象,然后一直传下去,直到该请求被响应。由于发起者只知道下一个是谁,而不清楚往后的处理者和处理细节,也实现了对象之间的解耦
空降地址:柠檬大师:看完就明白的责任链模式
总结
在实际开发过程中,并不是一定要求所有代码都遵循设计原则,而是要综合考虑人力、时间、成本、质量,不刻意追求完美,不为了设计而设计,一定要结合实际。可以帮助我们设计出更加优雅的代码结构。
所有模式学完,感觉有的很相似,有的也记不大住,使用了设计模式反而比不使用设计模式使程序看起来更加复杂,而不是更加简单。那是因为每篇文章的场景模拟都是无实际使用意义的示例代码,实际情况是程序非常复杂才需要使用到设计模式。
一个大型程序是不断迭代出来的,一开始肯定不长那样,日常接到一个需求也不要上来就想用什么设计模式,先实现功能,然后回头看看
公共代码都封装了吗?常用的方法能封装个工具类吗?
相同行为的一些对象是否能抽象一个接口?
是否将每个方法的功能都最小化了?
是每个类只干一件事情,写程序时候的每一步考虑,其实就是设计模式的思想,我们程序员做的,都是尽量的使工程做到高内聚,低耦合。这也是我们学习设计模式的初衷!
受之设计模式,用之设计模式