当前位置:网站首页>梁老师小课堂|谈谈模板方法模式
梁老师小课堂|谈谈模板方法模式
2020-11-08 23:53:00 【公众号_松华说】
众多设计模式中,我觉得模板方法模式是很好理解,也很值得深入研究的技巧。定义如下,在一个包含多个步骤的业务框架中,大部分步骤是固定不变,并且适用于多种业务场景,可变的步骤则留给子类独立实现,从而分离了稳定和变化。
使用这种模式稍不留心,就会出现一些奇奇怪怪的问题。第一个是多个抽象方法会修改相同的变量,方法间出现强关联,第二个问题是定义了过多的抽象方法。后者正是今天想和你聊的话题,跟着我的步伐往下看吧。
一、为什么会出现这种问题?
我认为是这样的,产品经理从业务角度告诉我们,这个功能涉及到哪些步骤,每个步骤需要完成哪些事,然后我们就照搬概念将其转换成代码,考虑到有些步骤会涉及到多个实现,于是留了很多扩展方法。
不久后,新的业务需要复用这些流程,需要步骤1\2\3,但是不需要步骤4\5,甚至看不懂步骤4\5是做什么的,也不知道什么条件下会被调用,原有设计就显得不够简单了。
怎么理解这里说的简单呢?简单是站在人的角度来看的。假如,定义者和实现者来自两个不同的团队,实现者阅读文档后还需要定义者解释,才知道怎样实现抽象方法是正确的,那它就是复杂的。这个是我的真实感受,之前我在做中台通用能力建设,通过扩展点对外赋能时,思考最多的就是如何让第三方快速理解并上手。
总结一下,生搬硬套需求文档,让执行顺序完整地反映在代码结构中,会导致模板方法模式出现了过多的抽象方法。
二、出现了怎么办?
出现了过多的抽象方法怎么办呢?其实我们可以利用接口适配器模式来打补丁。
实际做法是这样的,创建一个抽象类Wrapper,实现所有的方法,方法实现不需要具体业务含义。当我们编写具体实现类时,继承Wrapper类,重写它自己关心的方法,这样就不用实现不了解的步骤了。
使用接口适配器来兼容可能还不够,考虑这样的情况,模板中的抽象方法明确需要有返回值,要怎么处理呢?
看来只好继续打补丁了。比如,定义一些默认值,业务流程中对这些值进行抛弃处理。或者,方法默认实现运行时抛出异常,表明不支持该操作,必须有第三方实现才行。这两个方案其实都不好。第一种有特殊逻辑,估计会被很多人鄙视。第二种方案相对优雅一些,缺点是调试过程才能发现异常。
总结一下,使用接口适配器模式,让子类只关心它需要的方法,这样就把旧代码、脏代码盘活了。
三、如何避免出现过多的抽象方法?
模板方法模式出现过多的抽象方法,侧面说明了流程步骤繁杂,不够简单。所以,这个问题的另外一种描述是,模板方法设计时如何避免暴露过多的细节。
我的建议是,对业务逻辑进行整理,把同类行为进行提取,或者把共享很多信息的方法合并,用一个通用的术语来概括这个环节,把细节隐藏起来,再用组合的方式加载进来,不要把代码直接平铺。
举例说明一下。在一个请求链路中,中间方法通过缓存客户端直接控制缓存的清除、缓存值的设置,其他链路则读取缓存值。这种编码风格,会把缓存Key、缓存组件暴露给第三方,导致后续修改困难。正常应该新建一个业务类,专门与该缓存Key打交道。
总结一下,避免出现过多的抽象方法的关键是如何避免暴露过多的细节。
本文分享自微信公众号 - 松华说(songhuasay)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
版权声明
本文为[公众号_松华说]所创,转载请带上原文链接,感谢
https://my.oschina.net/liangsonghua/blog/4708396
边栏推荐
猜你喜欢
构造函数和原型
Creating a text cloud or label cloud in Python
解决IE、firefox浏览器下JS的new Date()的值为Invalid Date、NaN-NaN的问题
Aprelu: cross border application, adaptive relu | IEEE tie 2020 for machine fault detection
Factory Pattern模式(简单工厂、工厂方法、抽象工厂模式)
VIM Introduction Manual, (vs Code)
动态规划之子序列问题解题模板
Looking for better dynamic getter and setter solutions
几行代码轻松实现跨系统传递 traceId,再也不用担心对不上日志了!
Python features and building environment
随机推荐
实验一作业
老大问我:“建表为啥还设置个自增 id ?用流水号当主键不正好么?”
综合架构的简述
APReLU:跨界应用,用于机器故障检测的自适应ReLU | IEEE TIE 2020
实现图片的复制
200 programmers interview experience, all here
Decorator (1)
构造回文的最小插入次数
Swagger介绍和应用
Table join
动态规划设计:最大子数组
Octave基本语法
AI人工智能编程培训学什么课程?
JVM Zhenxiang series: easy understanding of class files to virtual machines (Part 2)
教你如何 分析 Android ANR 问题
C / C + + learning diary: original code, inverse code and complement code
C/C++学习日记:原码、反码和补码
新手入坑指南:工作原因“重启”Deepin系统,发现真的香啊
Test comparison of three domestic cloud databases
动态规划之子序列问题解题模板