装饰者模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
该模式又称套娃模式
应用场景
场景举例
Java实现
应用场景大家都见过流中套娃的写法,类似如下
1new BufferedInputStream(new FileInputStream(new File("")));
如类似的实现关系,如图
装饰者模式就是这样的写法,将对象动态增加功能,而不改变原有的功能
怎么体现不改变原有代码,而动态增加职责?
场景举例目前有一个咖啡接口,可以有众多咖啡实现,比如星巴克,瑞幸,类图如下,这也是原始的代码
类代码如下
接口
123public interface ICoffee { void getCoffee();}
星巴克
123456public class StarBucksCoffee implements ICoffee{ @Override public void getCoffee() { System.out.println(&q ...
中介者模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
中介者模式其实也就是字面意思,跟你买房的时候往往需要找个中介一样。中介会帮你处理所有事情,你只需要与中介一个人建立联系就可以。那么跟之前学习的代理模式有什么不同之处,代理是完成类和增强类的功能,中介主要是为了解耦
没有中介之前的模式类似于网状结构,不仅你需要跟每个人联系,而且需要他们互相之前也去建立联系,令人头疼的是这种结构往往牵一发而动全身
网状结构
有中介之后类似于星状结构,所有人都找中介,大大降低了耦合性
星状结构
定义
优点
缺点
角色
场景模拟
总结
定义中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。是迪米特法则的典型应用。
优点降低各个对象的耦合性,使系统易于维护与扩展
缺点每添加对象,就需要在中介处更新,如果对象过多,中介类就会变的臃肿,复杂难以维护
中介出问题,整个程序玩完,道理和卖房中介卷钱跑路一样
角色抽象中介者(Mediator):中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者(C ...
模(mu)板模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
定义
优点
缺点
应用场景
使用场景
钩子方法
场景举例
定义定义一个操作中的算法骨架,将算法的一些子步骤延伸到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤
优点1、封装不变部分,扩展可变部分,不变的封装到父类实现,可变的由子类去扩展
2、便于代码复用,易于拓展,符合开闭原则
缺点1、父类的方法由子类实现,是一种反向控制,提高代码阅读难度
应用场景使用spring的都用过
12ApplicationContext ac = new ClassPathXmlApplicationContext(“classpath:/*.xml”);ac.getBean("bean")
这个类的就是模板方法子类的一种体现,通过不断的继承重写父类方法,子类所需要实现的方法越来越少,也可以看出该模式是一种反向控制模式
1234567891011121314151617181920212223242526272829303132333435363738@O ...
命令模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
小米之家的一些家电,用一个app就可以进行控制,每个智能产品只需要提供一个统一的接口给小米app调用就行了,这就用到了命令模式
定义
通用类图
角色
场景举例
总结
定义向某些对象发送请求,但不知道请求的接收者是谁,也不知道被请求的操作是哪一个,此时可以采用命令模式
发布者只管发送命令,不管谁去执行。不直接指挥执行者,而是通过命令类去处理
通用类图
角色Command:命令角色,可以是接口或者抽象类
ConcreateCommand:定义具体命令
Receiver:接收者角色,等待命令并执行
Invoker:调用者,按照客户端指令执行命令,包括撤销命令
命令模式的精髓就是命令者并不需要知道谁去执行这个命令,比如老板让秘书去打印一些文件,命令就是打印文件,秘书在交给具体打印者去打印,老板不关心是小王还是小李打印
场景举例小王买了两个机器人A,B。A会唱歌,跳舞。B会炒菜。小王可以发布命令“唱歌,跳舞,炒菜”
uml类图设计
抽象类Command
123public interfac ...
备忘录模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
定义
应用场景
优点
缺点
角色
场景模拟
总结
定义记录某一时刻的状态,以便用到的时候恢复
应用场景ctrl+z、快照,回滚,游戏存档,悔棋,相关的备份操作
优点在需要的时候可以很方便的恢复需要的状态
缺点频繁保存会消耗大量资源
角色发起者(Originator):记录状态信息,同时可以访问备忘录中的信息
备忘录(Memento):储存发起人的内部状态
管理者(Caretaker):用于保存和获取备忘录功能,但不能修改
场景模拟模拟小游戏打怪场景,一个怪2分,可以存档和读档
调用场景实现
1234567891011121314151617181920212223Originator originator = new Originator();CareTaker careTaker = new CareTaker();//开始游戏System.out.println("开始游戏,杀死一个小怪得2分");//开始杀怪originator.kill();origin ...
状态模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
定义
优点
角色
场景举例
总结
定义将复杂的逻辑判断提取到不同的状态对象中,允许内部状态发生改变时改变其行为
优点结构清晰,满足单一职责,减少对象的相互依赖,易于程序扩展
角色上下文(Context):它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
抽象状态(State):定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
具体状态(Concrete State):实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
场景举例线程生命周期举例
如图,存在5种状态,在每个状态获得一定条件之后会转换为其他状态
如果用传统的方式实现,if/switch利用现在的状态来做这个状态下的行为
伪代码实现
123456789if (o instanceof InitialState) { //新建状态调用} else if (o instanceof Runnable) { //就绪状态调用& ...
解释器模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
定义
用的原因
缺点
角色
场景举例
定义用编译语言的方式来分析应用中的实例
为什么要用扩展性好,利用继承机制扩展文法
缺点效率低,调用麻烦,容易引起类膨胀,这个模式很少能用到
角色抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
终结符表达式(Terminal Expression):是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
非终结符表达式(Nonterminal Expression):也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
上下文(Context):通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
场景举例设计一个读卡器,北京或太原的老年和孕妇刷卡免费,其余人群标准价
首先设计文法
123< ...
策略模式
设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
定义
使用场景
角色
场景举例
定义该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户
使用场景有些问题存在一题多解的情况,这时候往往需要if结构去判断调用其行为,可以考虑使用该模式
角色抽象策略(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy):实现了抽象策略定义的接口,提供具体的算法实现。
环境(Context):持有一个策略类的引用,最终给客户端调用。
场景举例王老板打算去约会,打算考虑一种出行方案,既省钱又快速,方案如下
1、公交:1块/km,用时30分钟
2、打车:3km起步价5块,超1km加2块
3、单车:2块/5km
传统写法是这么调用的
1234567891011121314151617181920212223242526public static int fee(String ...