模板模式和策略模式的区别

根据《深入浅出设计模式(C#/Java版)》所述,


Strategy模式的应用场景是:
1. 多个类的分别只是在于行为不同
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据

 

Template Method模式的应用场景是:
1. 你想将相同的算法放在一个类中,将算法变化的部分放在子类中实现
2. 子类公共的算法应该放在一个公共的类中,避免代码重复

 

仔细体会作者所提出的这几个应用场景,你会发现它们其实没什么区别,用Strategy或Template Method模式都能完成要求.换句话说,作者没抓住这两个模式区别的"痛处"来给予详细讲解.下面我们再换个出发点来看看这两种设计模式.

 

我们知道,设计模式中有这么一个原则: Prefer composition to inheritance.这句话的背景是OO初期大家都把继承看作是万能的,并过度使用继承来实现多态->可扩展.理解原则的时候不能脱离它的背景,不然就成盲从了.Template Method模式应该是伴随着OO的出现而萌生的.它是OO中最直观的思考方式的结果.基类留下可变化的空间给子类,由继承类来决定具体行为.听起来是不错,不过...一旦基类的接口发生了变化,每个继承类都得跟着修改才能够继续使用.这就是所谓高耦合与难维护的说法的来源.

 

Strategy与Template Method模式算是composition与inheritance的典型应用了,如果它们真的在功能上能完全互换,那何必要后者呢,全部都用前者不是很好么? 再怎么说,一个倾向于加深类层次结构的设计通常会使设计变得复杂,令后期维护变得困难.

When deciding between inheritance and composition, ask if you need to upcast to the base type. If not, prefer composition (member objects) to inheritance. This can eliminate the perceived need for multiple base types.

Which should I prefer: composition or private inheritance? Use composition when you can, private inheritance when you have to.

有一个说法总结得不错: 到底该倾向于composition还是inheritance,决定于"变化的是什么".如果基类的接口变化得很频繁,那么使用inheritance绝对是个噩梦;如果只是给基类新增方法,那么坚持使用composition的话就得新增很多个delegate.

这么说来,Strategy与Template Method模式之间的区别,也是在"变化的是什么"这个问题上了.

 

注意到,Strategy模式中,为了让Context类能够调用,Strategy接口里声明的方法一般是公有的.Template Method模式则不然,基类中留下的虚方法并不一定要是公有的,只要保证对继承类可见就行.也就是说,Template Method模式允许编写库的人采取更紧的访问限制,而Strategy模式则很难做到相同等级的限制.假如使用者获得了一个Strategy接口的实现类的实例,他并不一定要将这个实例放入"原本应有"的那个Context,而可以随意使用其中的接口方法.Template Method模式可以利用protected的访问权限,牺牲一点面向对象的封装性,给自己的继承类一定的访问特权,来把一些访问限制在"体系内",从而限制了外部对内的访问.这仍然只是表象,不过我们已经接近问题的本质了.

 

这带来的区别是什么呢? Strategy模式允许外界使用其接口方法,因而可以将这个接口方法认为是"一整个算法";而Template Method模式可以限制所留下的虚方法只对其继承类可见,外部使用者不一定能够直接使用这些虚方法,因而可以将这些虚方法认为是"一个算法的一部分".GoF的设计模式那本书里有这么一句话:"Template methods use inheritance to vary part of an algorithm. Strategies use delegation to vary the entire algorithm.",说的正是这个问题.回到具体问题上,如果我们要封装的算法适合于提供给用户任意使用,是"一整个算法",那么用Strategy模式较好;如果要封装的变化是一个算法中的部分(换言之,大算法的步骤是固定的),而且我们不希望用户直接使用这些方法,那么应该使用Template Method模式.就此,问题的"痛处"算是抓住了.


根据两种模式的定义,可以总结其适用场景,策略模式适合每种算法之间的差异很大,基本没有多少共同的地方,这样才能保证不同的算法之间不存在重复的代码,所以在采用此模式前要将服务细化,将大粒度的服务拆成细粒度的;而模板方法模式则适合每种算法的总流程基本一致,差别只是在具体的子过程实现上,在应用此模式前要保证总流程是相对稳定的,在具体子过程上如果存在相同的部分,也可以结合策略模式,将子过程的实现定义成一个个策略。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值