准备完成《Head First》模式上讲的策略模式,就是小鸭子问题。
准备用Python来实现这个设计模式。
遇到问题如下:
1.Python没有类似于Java的动态绑定机制,所以谈不上基于父类引用的多态实现
2.Python如何实现多态
通过查找一些资料,发现Python,其实不只是Python,动态语言都采用Duck_Typing来实现
什么是Duck_Typing
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
例子如下:
class Duck:
def quack(self):
print(“Quaaaaaack!”)
def feathers(self):
print(“The duck has white and gray feathers.”)
class Person:
def quack(self):
print(“The person imitates a duck.”)
def feathers(self):
print(“The person takes a feather from the ground and shows it.”)
def name(self):
print(“John Smith”)
def in_the_forest(duck):
try:
duck.quack()
duck.feathers()
except (AttributeError, TypeError):
print(“can’t quack()”)
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
game()
这段代码是维基百科中的 例子, 我稍微加了一点关于异常的代码。这段代码实现了in_the_forest方法的多态,相较于Java和C++,不需要通过父类的引用,即可直接实现多态。
造成这种多态实现方式的不同, 个人认为主要还是由语言特性决定的(静态语言与动态语言的区别)。虽然Python,C++,Java都是强类型语言,但Python因为动态语言的这个特性,不需要强制声明参数类型。这样的特性可以是我们编写的时候只专注于方法的使用,而不需要过去考虑对象的类型。
相较于继承所产生的树形层级结构,Duck_Typing可以使多态平行化。两个没有任何继承关系的类,只要拥有相同的方法,也可以作为参数传入。
顺带提到的还有重载问题,重载到底是什么,如果语言没有提供重载机制那么是否可以实现重载。
个人的想法是可以实现,拿C来说,个人认为通过使用可变参数就可以实现函数重载。
至于Python,同样可以通过args 或者 *kwarg来实现