admin管理员组文章数量:1794759
深入浅出设计模式
大家好,我是小士。
在第一次做项目的时候,写代码毫不顾忌,只想着把功能实现了就好。随着项目的推进,需求越变越多,写代码的效率越来越低,最后连自己写的代码都看不懂了。当时前辈给我推荐了《深入浅出设计模式》这本书。让我学习一下设计模式。常用的设计模式来来去去就那么几个,背熟了以后对写代码受益无穷。于是,笔者之后计划着每周从这本书中学习一个设计模式。
这本书的示例代码主要用java编写。因为个人平时更民俗学习惯用python写代码,所以更习惯基于python来理解设计模式。本文会把学习过程中的笔记和python代码分享给大家。由于《深入浅出设计模式》已经对每个模式的由来讲得非常细致了,本系列只是对学到的设计模式进行一个总结。
代码需求原书用一个设计模拟鸭子游戏的例子来解释什么是策略模式。假如老板要求你设计一款模拟鸭子的游戏,而他需要每种鸭子有不同的叫声腾讯军事、外观、或其他可能新增的需求(╯‵□′)╯︵┴─一休哥图片┴。
这个问题其实并不难,只要需求给定了我们能很快实现一版代码。但是在实际场景中,需求总是越来越多的。为了更高效地实现新需求,我们写的代码需要兼顾「可复用性」和「可拓展性」。
继承和组合原书主要对比了两种风格的代码:「继承」为主的和「组合」为主的。继承为主的代码可复用性高但是可拓展性差;组合为主的代码可拓展性高,可复用性也不差。策略模式以组合为主,它的核心思想是「将独立的模块组合起来」。
继承为主的代码结构如下图所示:
继承为主的代码问题主要体现在橡皮鸭(RubberDuck)的实现上。运营是做什么的一开始定义父类Duck的时候,没有考虑到会存在橡皮鸭这种不会飞且吱吱叫的鸭子,导致了橡皮鸭的fly方法和quack方法需要重写。索尼广角镜头橡皮鸭的实现已经几乎相当于把父类Duck重写一遍了。但如果未来又加入一个不会飞也不会叫的鸭子怎么办,总不能再重写一遍吧?
计划赶不上变化,想不到的需求才是常态。尽管一开始是「为了提高可复用性才用了继承结构」的,但因为需求千奇百怪,继承结构经常「不能保证新的子类一定能复用父类的方法」。
而组合为主的代码能很好地避免这一问题。我们注意到,Duck类一般不需要修改,而fly和quaradius协议ck方法「经常需要修改」。我们把需要经常修改的地方「抽出来」,分别做成一个个「独立的模块」(FlyBehavior和QuackBehavior),最后再将他们「组合」回D苏州西园寺uck。最后得到代码结构如下图
相比于继承为主的代码,它重新定义了两个父类FlyBehavio猫的习性r和QuackBehavior。这两个父类将飞行行为和叫声「封装」起来,将它们变成独霍乱时期的爱情立的两个模块。如果需要增加新的飞行行为和叫声,我们可以直接继承FlyBehavior和QuackBehavior来实现新的需求,而不影响以前已经实现好的功能。
策略模式总结策略模式的核心思想就是「将独立的模块组合起来」。策略模式通过定义「算法族」,并将它们分别「封装」起来,让它们之间可以相互替换。此模式让算法的变化「独立」于使城市gdp排名用算法的客户。
依据策略模式来设计代码一般分为三个步骤:
找出应用中可能需要变化之处,将它们「封装」成独立的模块;分别「实现」独立的模块;将它们「组合」到一起。少用继承,多用组合。为了复用代码而使用继承,会限制代码可拓展性,难以应付新的需求,最后结果反而可能更糟。
参考文献Head First Design Patterns, 2nd Edition《Head First 设计模式》学实习周报习笔记 | 策略模式 (jalan.space/2020/03/09/2020/)design-pattern-strategy-pattern/附录代码继承风格的python实现如下:
class Duck: def quack(self): 虚拟天空 print('呱呱叫') def swim(self): print('会游泳') def fly(self): print('会飞') def display(self): raise NotImplementedErrorclass MallardDuck(Duck): 舒赛 d巴黎综合征ef display(self): print('未完成的故事;外观是绿头')class RedheadDuck(Duck): def display(self): print('外观是红头')class RubberDuck(Duck): def quack(): print('吱吱叫') def fly(): 南中医 print('不会飞,什么事都不能做') def display(self): print(明星护肤39;外观是橡皮鸭')组合风格的python实现分为三个部分:QuackBehavior, FlyBehavior, 和Duck。QuackBehavior部分为。具体实现如下:
# QuackBehaviorclass QuackBehavior(): def quack(self,): raise NotImplementedErrorclass Quack(QuackBehavior): def qu壁画ack(self,): print('呱呱叫')class Squeak(): def quack(self,): print('吱吱叫')class MuteQuack(): def quack(self,): print('不会叫')# FlyBehaviorclass FlyBehavior: def fly(self,): raise NotImplementedErrorclass FlyWithWings(FlyBehavior): def fly(self,): print('我在飞行')class FlyNoWay(FlyBehavior): def fly(self,): print('不会飞')# Duckclass Duck: def __init__(self,): self.flyBehavior = None self.quackBehavior = None def performFly(self): self.flyBehavior.fly() def performQuack(self): self.quackBehavior.quack() def swim(self): print('会游泳') def display(self): raise NotImplementedErrorclass MallardDuck(Duck): def __init__(self,): self.flyBehavior = FlyWithWings() self.quackBehavior = Quack() def display(self): print('外观是绿头')class RedheadDuck(Duck): def __init__(self,): 吉他时代 self.对数运算法则flyBehavior = FlyWithWings() self.quackBehavior = Quack() def display(self): print('外观是红头')class RubberDuck(Duck): def __init__(self,): self.flyBehavior = Squeak() self.quackBehavior = FlyNoWay() def display(self): print('外观是橡皮鸭')if __name__=="__main__": duck = MallardDuck() duck.performQuack() duck.performFly()更多算法基础知识介绍,前沿论文解读,欢迎关注微信公众号,口袋AI算法:
版权声明:本文标题:深入浅出设计模式 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1685938831a14006.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论