学设计模式的这段时间:一个管骨架,一个管替换

发布时间:2026/8/2 8:14:03
学设计模式的这段时间:一个管骨架,一个管替换 最近在补设计模式。以前也翻过几回每次都是看到定义就关了每个字都认识连在一起不知道在说什么。这次换了个学法先找例子再看定义然后用自己的话写一遍写不出来的地方就是没懂的地方回头再补。这篇是边学边写的记录写到哪算哪。为什么突然想学其实我说不上什么具体契机。就是模板方法策略这两个词老在眼前晃看别人的代码、看网上的讨论动不动就冒出来躲了几次发现躲不掉索性认真搞一次。先从这两个开始。没学之前我对这两个词的第一印象先说说没学之前的理解现在回头看挺搞笑的。“模板方法”我以为是模板。心想是不是像网页模板那样套一套就能用那方法应该就是函数合起来大概是个偷懒技巧把函数做成模板。“策略这个词更唬人听起来像兵法。我猜是面对不同情况用不同招”。说实话这个直觉方向不算错但也只是方向对具体是什么完全不知道。第一次认真看定义看到的是两句话模板方法模式定义一个操作中的算法骨架而将一些步骤延迟到子类中。策略模式定义一族算法分别封装起来让它们可以互相替换。看完就一个感觉每个字都认识。合上书问我这俩是干嘛的一个字都说不出来。那时候我对这两个模式的全部理解就是都是把变化抽出来这个理解现在看也不算错但当时等于没说因为我不知道抽具体指什么、怎么抽、抽完放哪。那会儿还想过一个问题设计模式这种东西是不是得工作好几年才能看懂我一个代码都还没写利索的人现在学是不是太早。后来想想反正躲不掉了学吧。模板方法模式流程固定步骤可变先说模板方法。我理解它的套路是这样一个抽象类里有个骨架方法骨架方法把整个流程定死第一步做什么、第二步做什么、最后做什么顺序不能乱。但骨架方法自己不干活它中间会调用几个抽象方法这些抽象方法留给子类去填。子类能改的是步骤的内容改不了流程的顺序。我第一次看懂这个结构的时候脑子里蹦出来的话是这不就是继承吗父类写个方法子类重写这不是最普通的用法吗为什么要单独起个名字。这个困惑卡了我一阵。后来慢慢想明白区别在哪普通的继承父类方法是你可以重写模板方法里骨架方法是流程我定死了你只许填我留给你的空。区别在主动权。骨架方法像个指挥流程顺序它说了算子类是被指挥着干活的人。你可以把洗碗这步换成机洗但不能把先洗碗再擦桌子改成先擦桌子再洗碗。我给自己总结了一句话流程固定步骤可变。这八个字我到现在还记得因为是我自己琢磨出来的不是抄的。再配一个我自己的类比像考试。卷子的流程是出卷人定死的先选择、再填空、后大题答题人改不了。但每道题怎么答是答题人自己的事。骨架方法就是卷子抽象方法就是题。还有个细节我纠结了一下骨架方法在 Java 里一般写成 final不让子类重写。我理解这是为了防止子类把流程改乱既然设计意图就是流程我定死了干脆从语法上堵死这条路。不过这个理解我没验证过只是觉得合理。这个模式解决什么问题我现在的理解是它把重复的流程代码上收到父类每个子类只写自己不一样的那部分。流程要改的时候只改骨架那一处不用每个子类都动。好处挺直观但我还没在真实项目里用过只能说到我理解是这个程度。策略模式给会变的东西立个统一标准再说策略模式。这个我是从我自己笔记上的一句话开始的笔记上写着策略模式统一抽象这六个字当时只记了这六个字现在展开写写我当时到底想记什么。先说我理解的套路一个接口几个实现类再加一个上下文。接口把做什么定下来实现类各自给出怎么做上下文只管调用接口不关心背后具体是谁。要用哪种做法从外面塞进去就行。我为什么记统一抽象因为策略模式干的事在我看就是把会变的那部分单独拎出来给它立一个统一的标准也就是接口。所有变体都遵守这个标准调用方看到的永远是标准的样子不用管背后是哪家。这就是我理解的统一和抽象用一个接口把一堆长得不一样的东西统一成同一个样子给外面用。类比我想到两个。一个是换轮胎轮毂上的螺丝规格是统一的米其林、马牌、朝阳随便换都能装上。接口就是那个螺丝规格具体轮胎就是各个实现。另一个是支付微信、支付宝、银行卡都实现同一个支付接口收银台不用管顾客用什么付反正都是支付。学到这里卡点来了这俩模式也太像了吧。模板方法把变化的部分抽出来让子类实现。策略把变化的部分抽出来让实现类替换。都是把变化抽出来凭什么一个叫模板方法、一个叫策略这个问题我琢磨了好几天说下我现在的理解不一定对。区别我琢磨出来三个。一个是抽法模板方法是继承父类定流程、子类填步骤变化是往子类里藏的策略是组合上下文拿着接口引用策略从外面塞进去变化是往外拎的。一个是纵向一个是横向。另一个是变的粒度模板方法变的是流程里的某几步流程整体还在策略变的是整个行为是整块算法换掉。还有一个是换的方式模板方法里用哪个实现是跟着子类走的子类类型定下来步骤就跟着定了策略模式里同一个对象可以随时换策略程序跑着跑着换掉行为就变了。这个运行时能换的特点是我觉得策略和模板方法最本质的区别也是我反复确认了好几遍才敢写下来的。对了还有个一开始误会我的地方策略模式的定义里说算法我差点以为只有排序、搜索这种东西才配叫策略。后来才明白这里的算法是泛指任何一种做法方式都可以是策略。现在想想定义里算法两个字确实容易劝退新人。试着动手写一半卡住了光看不行我试着写。本来想写一个完整的例子一个场景分别用两个模式实现一遍对比着看。结果写到一半就卡住了代码到现在还没跑通先不贴了等跑通了再补。卡在哪卡在选场景。想用模板方法但我脑子里的场景不是流程不够固定就是一共两步写个继承纯属折腾。想用策略倒是好找一个功能有好几种做法、按输入选不同的做法这种就很自然。但我也只是想象这种场景不是真做过。这一卡让我对模板方法多了一层理解它不是随便用的。得流程真的稳定、步骤真的会变才划算。要是流程三天两头变或者根本没什么可变步骤硬套模板方法就是白加一层类反而更绕。这个想法没有实践验证过但至少现在写代码之前我会先问自己一句这个流程真的固定吗不固定模板方法就先别碰。我还干了一件事把两个模式的结构用我自己的话各写了一遍然后互相问为什么这个场景不用另一个。模板方法管的是流程不变、细节变策略管的是整个行为变、随便换。这么一写边界好像清楚了一点。但真到具体场景我还是会犹豫。比如一个场景里流程是固定的但流程里某一步的做法有好几种这算模板方法还是策略我现在的答案是看粒度步骤级的变用模板方法整个行为级的换用策略。但说实话这也是我自己的感觉没有标准答案可查。另外看例子的时候注意到一个现象策略模式在真实代码里很少是一个接口加一堆实现类这么干净的经常跟工厂、跟注册表什么的混在一起用。这个我还没搞明白先记下来等以后遇到了再说。现在能说清的和还没搞懂的学到这儿让我用一句话说这俩模式我会说模板方法模式流程骨架定死在父类子类只填可变步骤。用继承。策略模式把整个行为抽象成接口调用方只认接口实现随便换。用组合。跟没学之前比最大的变化是以前听到这俩名字就绕道现在至少知道它们在解决什么问题、大概长什么样。但距离会用还差得远。还没搞懂的我列一下一是什么时候该用哪个我还是凭感觉没有一套自己能说出口的判断标准。二是钩子方法。模板方法里除了抽象方法还有一种叫钩子的东西子类可以不覆盖覆盖了就能控制流程里的可选步骤。抽象方法我搞懂了钩子方法跟它的边界我还没完全摸清。三是策略模式混在其他模式里我就认不出来了真实代码比教程复杂太多。四是我笔记里那句统一抽象是我自己的说法不是标准术语如果理解偏了欢迎指正。这篇是边学边写的记录写的时候又卡了几次卡住的地方反而记得最牢。跟以前比我学东西的方式变了点不背定义先看例子再用自己的话复述复述不出来的就是没懂回头再补。设计模式这名字唬人拆开了也就是一些常见问题的常见解法只是没人早点告诉我该从哪头看。