设计模式(一):策略模式
书面定义
策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户
内容
我们的目的是设计一个鸭子类,作为其他鸭子的基类
按照设计原则,应该将经常变更的部分提取出来,独立成为一个部分。
以鸭子类来说,假如需要设计一个基类,什么地方会是不变的呢?
- 鸭子与叫声有关(这里将不会叫也作为会叫的一种)
- 鸭子与飞有关(不会飞也作为一种飞)
- 鸭子与游泳有关
所以首先设计一种类:
class Duck:
def quack(self):
pass
def swim(self):
print("I can swim")
def display(self):
pass
def fly(self):
print("I can fly.")
找到一只橡皮鸭(继承Duck类)
class RubberDuck(Duck):
def display(self):
print("I am rubber duck")
duck1 = RubberDuck()
duck1.fly() # I can fly.
很明显,橡皮鸭不会飞,但是却显示其能飞(fly方法对RubberDuck类毫无作用)
在最先设计的类中,所有继承Duck类的子类都会有quack,swim,fly方法,即使它们不会叫,不会飞,不会游泳。
所以,在代码上,就造成了冗余,有些部分根本就不需要,同样,并不是所有的子类都能够完美使用方法
比如,所有继承该类的类都会有一个fly方法,即使这种鸭子并不会飞。
修改过如下
class FlyBehavior: # 飞行行为的接口
def fly(self):
pass
class QuackBehavior: # 叫的接口
def quack(self):
pass
class FlyWithWings(FlyBehavior): # 各种飞行方式的具体实现
def fly(self):
print("I can fly")
class FlyNoWay(FlyBehavior):
def fly(self):
print("I can't fly")
class Quack(QuackBehavior): # 各种叫的方式的具体实现
def quack(self):
print("quack")
class Squeak(QuackBehavior):
def quack(self):
print("squeak")
class MuteQuack(QuackBehavior):
def quack(self):
print("I can't quack")
class Duck:
fly_behavior = None
quack_behavior = None
def swim(self):
print("I can swim")
def display(self):
pass
def perform_fly(self):
self.fly_behavior.fly()
def perform_quack(self):
self.quack_behavior.quack()
class RubberDuck(Duck):
def __init__(self):
fly_behavior = FlyNoWay()
quack_behavior = Squeak()
def display(self):
print("I am Rubber duck")
duck1 = RubberDuck()
duck1.perform_fly() # I can't fly
duck1.perform_quack() # squeak
将fly和quack抽象为FlyBehavior和QuackBehavior接口(interface),接口统合了各类方法,对外暴露了同一个方法,内部使用不同方式实现。
所以,鸭子就可以使用各种方式进行fly和quack(可以对fly和quack的实现进行任意的修改,从而不怕影响到其他类,实现了低耦合)
这时候,如果想要加入一个火箭鸭(创建一个新的RocketDuck类,该类继承Duck类),只要再定义一个行为即可
#-*- coding:utf-8 -*-
class FlyBehavior: # 飞行行为的接口
def fly(self):
pass
class FlyWithWings(FlyBehavior): # 各种飞行行为的具体实现
def fly(self):
print("I can fly")
class FlyNoWay(FlyBehavior):
def fly(self):
print("I can't fly")
class FlyWithRocket(FlyBehavior):
def fly(self):
print("I can fly with Rocket")
class QuackBehavior: # 叫的行为的接口
def quack(self):
pass
class Quack(QuackBehavior): # 各种叫的方式的具体实现
def quack(self):
print("quack")
class Squeak(QuackBehavior):
def quack(self):
print("squeak")
class MuteQuack(QuackBehavior):
def quack(self):
print("I can't quack")
class Duck:
fly_behavior = None
quack_behavior = None
def set_fly_behavior(self, fb):
self.fly_behavior = fb
def set_quack_behavior(self, qb):
self.quack_behavior = qb
def swim(self):
print("I can swim")
def display(self):
pass
def perform_fly(self):
self.fly_behavior.fly()
def perform_quack(self):
self.quack_behavior.quack()
class RocketDuck(Duck):
fly_behavior = FlyWithRocket()
quack_behavior = MuteQuack()
def display(self):
print("I am ROCKET duck!")
duck1 = RedheadDuck()
duck1.perform_fly() # I can fly with Rocket
duck1.perform_quack() # I can't quack
参考资料
《head first 设计模式》