当前位置:网站首页>梁老师小课堂|谈谈模板方法模式
梁老师小课堂|谈谈模板方法模式
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
边栏推荐
猜你喜欢
装饰器(二)
Decorator (2)
Five factors to consider before choosing API management platform
Octave basic syntax
Introduction skills of big data software learning
Why need to use API management platform
Dynamic ReLU:微软推出提点神器,可能是最好的ReLU改进 | ECCV 2020
Newbe.ObjectVisitor Example 1
Dynamic relu: Microsoft's refreshing device may be the best relu improvement | ECCV 2020
API生命周期的5个阶段
随机推荐
Using containers to store table data
[cloud service] there are so many ECS instances on alicloud server, how to select the type? Best practice note
老大问我:“建表为啥还设置个自增 id ?用流水号当主键不正好么?”
Flink's datasource Trilogy 3: customization
SAP S/4HANA 2020安装实录
Leetcode 45 jumping game II
Problem solving templates for subsequence problems in dynamic programming
使用递增计数器的线程同步工具 —— 信号量,它的原理是什么样子的?
What courses will AI programming learn?
Dynamic planning
Factory pattern pattern pattern (simple factory, factory method, abstract factory pattern)
STC转STM32第一次开发
计算机网络 应用层
salesforce零基础学习(九十八)Salesforce Connect & External Object
移动大数据自有网站精准营销精准获客
AQS 都看完了,Condition 原理可不能少!
大数据岗位基础要求有哪些?
信息安全课程设计第一周任务(7条指令的分析)
Fiddler can't grab requests from browsers like Google_ Solution
getBytes之 LengthFieldBasedFrameDecoder服务端解析