设计模式复习小结 - 详解
1.容易忘得设计原则
接口隔离:指接口中的功能太杂则可以拆分一下。防止建立类实现了接口后自动依赖了一些不需要的功能。不同功能拆分成不同的接口。
里氏代换:强调父类能出现的地方,子类一定能正常跑。
迪米特法则:又称最少知识原则,只与直接朋友通信,提高模块独立性。
单一职责,合成复用,开闭原则
依赖倒转: 指聚合/组合时使用抽象而非具体的子实现类。对抽象编程。降低客户与实现模块之间的藕合。“父类引用指向子类对象” 这说明 依赖倒转结合使用了里氏代换原则。
2、控制反转,指我写了一套抽象的支付代码,spring帮我去管理是阿里支付还是微信支付。
这个概念建立在依赖倒转原则上。即编码基于抽象。
依赖倒转是说我依赖的时候不依赖具体实现了,我依赖倒转了,变成了依赖抽象。
控制反转强调的是谁创建对象。比如由容器进行构造器注入,setter注入等。
我先依赖倒转,依赖抽象支付设备,写抽象代码,然后控制反转注入bean交给spring。这样我的工作就大大简化。不需要自己去太多关注支付方式。
3.关于适配器模式 与 桥接模式的联系与区别。
适配器的典型用法: 事后补救,解决接口不兼容的疑问。
class Adapter implements NewInterface {
private LegacyClass legacyObj;
适配器类实现新接口,但是组合老的实现类。通过老的实现类的技巧作为input,经过一定的转换,来返回新接口途径格式的结果。
桥接模式的典型用法:事前规划。选取一个主维度作为主体,去组合其他的维度。
抽象层与实现分离。比如统一的UI框架与不同OS的渲染。统一的数据格式与不同的db 驱动。
或者是多维度的分离,防止类爆炸。比如形状与颜色,车的类型与引擎的类型。
二者也经常结合采用。比如桥接模式定义一个抽象层,如数据存储,然后组合一个Adaptor类型的完成层。
这样在搭建一个具体数据存储的时候,可以去组合不同驱动类型的adaptor。
用抽象组合抽象。从而减少类定义的复杂度。就是回过头来,简单总结,这个桥接模式就
4.关于单一职责原则和接口隔离原则的练习与区别。
两者都体现了高内聚,低耦合理念。
不过单一职责强调类的职责,比如订单类与支付类的拆分。
接口隔离原则强调接口的拆分,比如飞行功能与汽车行驶的接口功能拆分。
5.访问者模式:
一句话总结: 不想在猫,狗类中写关于 健康检查,喂食等代码。
简单写一个accept 方法。调用入参的Visit。
具体的健康检查,喂食,由入参类负责。
另外一般会有一个动物园类来组合元素集合。并供应依次accept的技巧。方便兽医、喂食人员调用。
适合于你有一堆类似的元素(猫狗等),然后你又想将来以不同的方式来批量对待他们。
精髓是将操作从数据结构中分离出来,适用于处理易变,但数据结构稳定的系统。比如编译器,UI框架。
规避场景:数据结构容易变,或者不可预知的场景。即猫狗易变,而且我也不知道啥时候集合里面会多来一种动物。
游戏存档就是备忘录类 典型例子
存储游戏状态快照,但不想让其他人访问,随意修改材料。
Momento 对象,对其他人如玩家提供窄接口,仅对发起人(游戏程序员、GM、或者是材料敏感的GAMEROLE类这样的角色等)给予宽接口。
在java中的实现方案是,将PrivateMomento 设计为 GM类的成员内部类。
GM对外提供的backup restore 都是Momento类型。实际GM进行操作时,强转为PrivateMomento再在内部办法中偷偷操作属性等。
精髓:针对同样一个操作,实现双接口。对不同类暴漏的功能数量不一样。增强安全性。
对于无关的人,我给你一个功能很少的接口类。等到了底层真正执行的时候,你会发现它强转了向下转型了另外一个功能更强大的类。
7.状态模式
把状态抽象成类,对于同一个方法,当前是什么状态干什么事,减少if else 的启用。
比如向前Go订单。-> 现在是下单那就发货,是发货那就签收。
8.命令模式。
用一个 含有execute的 Command 接口。来解耦请求的发起与执行。
让请求的发起,关注命令即可,而不需要关注谁执行,如何去执行。
比如灯 implemens Command {
execute{ 灯.on }}
看了jdk 21的代码。 Collection 接口继承了 Iterable 接口。
public interface Collection extends Iterable
所以所有的集合类都支持迭代器。
责任链模式典型场景: 多层审批
实际精髓是一个很繁琐的活,我只要请求一次就行了。
典型写法 abstract class Handler{setNext(Handler)}
细分有纯(经典审批),不纯(如filter),动态排序的链(插件化架构)等。
DEBUG日志→控制台,ERROR日志→邮件+记录。
Web请求过滤
Servlet Filter链:身份验证→参数校验→业务处理。
拓展知识,filter依赖Servlet规范的doFilter函数,依赖 Servlet容器,可以拦截静态资源。
Interceptor基于动态代理搭建。依赖Spring框架,仅拦截Contoller请求(springBoot2.0之前。后来的版本需要手动放行一下)。可以访问Handler,ModelAndView等Spring上下文。
执行流程与顺序
Filter:
请求 → Tomcat容器 → Filter → Servlet
多个Filter按配置顺序链式执行(责任链模式)
Interceptor:
请求 → DispatcherServlet → Interceptor.preHandle() → Controller → Interceptor.postHandle() → 视图渲染 → Interceptor.afterCompletion()
协助更细粒度的生命周期控制(如preHandle返回false可中断请求)。
请求先经过Filter才进入DispatcherServlet。
所以先Fileter后intercepter。
掌握两者生命周期差异(Filter在Servlet前后,Interceptor在Controller前后),并强调Interceptor与Spring的协同优势(如Bean注入、路径精确控制)。实际项目中常组合使用,例如Filter处理全局安全,Interceptor处理业务权限。

浙公网安备 33010602011771号