在学习设计模式中的模板方法模式的时候了解到了一个比较陌生的名词——钩子方法,大概看了一下定义。
钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现
大概看懂了之后没有去深究,因为在编写代码的时候很少用到,也可能是代码写得少,但是最近在学习公司的插件编写的时候再次遇到了钩子方法的应用,在我们编写插件的时候如何让程序调用这个插件,但是又不去更改内部的代码,我们只需要编写好我们的插件或者更改插件就能做到改变程序的执行结果呢?这就涉及到了钩子方法。
在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。
这里引用了一下LoveLoin老师的文章中的定义,概念写的很清晰易懂,钩子方法就是通过子类的行为去反向控制父类的行为的一种方法,一般会和模板方法一起使用。
class TemplateMethod:
def play_video(self):
print('play video')
def play_picture(self):
print('play picture')
def gouzi(self):
self.play_video()
if bool_fun():
print('开始执行钩子方法')
self.gouzi_method()
self.play_picture()
def gouzi_method(self):
print('我是钩子')
def bool_fun():
return True
if __name__ == '__main__':
t = TemplateMethod()
t.gouzi()
python写起来比较别扭,不过也能从代码中看出来,我们写插件的时候只需要将bool_fun
方法修改一下,类中的gouzi
方法将根据bool_fun
(插件)方法的返回值来决定要不要执行gouzi_method
,那我们的bool_fun就可以做成包的形式导入到项目中,每次要更改程序运行之要更改bool_fun所在的文件就好了。
还有一种方法就是通过将父类中的钩子方法抽象进行抽象或者用虚方法实现钩子方法,让父类的一些方法延迟到子类去实现,但是pyhon没有虚方法这个概念,只能用抽象方法去实现。