首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >梁老师小课堂|谈谈模板方法模式

梁老师小课堂|谈谈模板方法模式

作者头像
公众号_松华说
发布2020-11-17 13:03:06
3600
发布2020-11-17 13:03:06
举报
文章被收录于专栏:松华说松华说松华说

众多设计模式中,我觉得模板方法模式是很好理解,也很值得深入研究的技巧。定义如下,在一个包含多个步骤的业务框架中,大部分步骤是固定不变,并且适用于多种业务场景,可变的步骤则留给子类独立实现,从而分离了稳定和变化。

使用这种模式稍不留心,就会出现一些奇奇怪怪的问题。第一个是多个抽象方法会修改相同的变量,方法间出现强关联,第二个问题是定义了过多的抽象方法。后者正是今天想和你聊的话题,跟着我的步伐往下看吧。

一、为什么会出现这种问题?

我认为是这样的,产品经理从业务角度告诉我们,这个功能涉及到哪些步骤,每个步骤需要完成哪些事,然后我们就照搬概念将其转换成代码,考虑到有些步骤会涉及到多个实现,于是留了很多扩展方法。

不久后,新的业务需要复用这些流程,需要步骤1\2\3,但是不需要步骤4\5,甚至看不懂步骤4\5是做什么的,也不知道什么条件下会被调用,原有设计就显得不够简单了。

怎么理解这里说的简单呢?简单是站在人的角度来看的。假如,定义者和实现者来自两个不同的团队,实现者阅读文档后还需要定义者解释,才知道怎样实现抽象方法是正确的,那它就是复杂的。这个是我的真实感受,之前我在做中台通用能力建设,通过扩展点对外赋能时,思考最多的就是如何让第三方快速理解并上手。

总结一下,生搬硬套需求文档,让执行顺序完整地反映在代码结构中,会导致模板方法模式出现了过多的抽象方法。

二、出现了怎么办?

出现了过多的抽象方法怎么办呢?其实我们可以利用接口适配器模式来打补丁。

实际做法是这样的,创建一个抽象类Wrapper,实现所有的方法,方法实现不需要具体业务含义。当我们编写具体实现类时,继承Wrapper类,重写它自己关心的方法,这样就不用实现不了解的步骤了。

使用接口适配器来兼容可能还不够,考虑这样的情况,模板中的抽象方法明确需要有返回值,要怎么处理呢?

看来只好继续打补丁了。比如,定义一些默认值,业务流程中对这些值进行抛弃处理。或者,方法默认实现运行时抛出异常,表明不支持该操作,必须有第三方实现才行。这两个方案其实都不好。第一种有特殊逻辑,估计会被很多人鄙视。第二种方案相对优雅一些,缺点是调试过程才能发现异常。

总结一下,使用接口适配器模式,让子类只关心它需要的方法,这样就把旧代码、脏代码盘活了。

三、如何避免出现过多的抽象方法?

模板方法模式出现过多的抽象方法,侧面说明了流程步骤繁杂,不够简单。所以,这个问题的另外一种描述是,模板方法设计时如何避免暴露过多的细节。

我的建议是,对业务逻辑进行整理,把同类行为进行提取,或者把共享很多信息的方法合并,用一个通用的术语来概括这个环节,把细节隐藏起来,再用组合的方式加载进来,不要把代码直接平铺。

举例说明一下。在一个请求链路中,中间方法通过缓存客户端直接控制缓存的清除、缓存值的设置,其他链路则读取缓存值。这种编码风格,会把缓存Key、缓存组件暴露给第三方,导致后续修改困难。正常应该新建一个业务类,专门与该缓存Key打交道。

总结一下,避免出现过多的抽象方法的关键是如何避免暴露过多的细节。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 松华说 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档