基于Python学习《Head First设计模式》 第一章 策略模式

抽象超类Animal

python 复制代码
from abc import ABC, abstractmethod

# 方式一
# class Animal:
#
#     def make_sound(self):
#         raise NotImplementedError('子类必须实现make_sound方法')

# 方式二
class Animal(ABC):
    """抽象类"""

    @abstractmethod
    def make_sound(self):
        """子类必须实现该方法,表示所有动物都能发出声音"""
        pass


class Dog(Animal):

    def make_sound(self):
        self._bark()

    def _bark(self):  # 单下划线表示仅内部调用,相当于java的private
        print("汪汪叫")


class Cat(Animal):

    def make_sound(self):
        self._meow()

    def _meow(self):
        print("喵喵叫")


if __name__ == '__main__':
    dog = Dog()
    dog.make_sound()

    cat = Cat()
    cat.make_sound()

实现鸭子的行为

python 复制代码
from abc import ABC, abstractmethod


class FlyBehavior:

    def fly(self):
        raise NotImplementedError

class FlyWithWings(FlyBehavior):

    def fly(self):
        print("鸭子飞行")

class FlyNoWay(FlyBehavior):

    def fly(self):
        print('不会飞')



class QuackBehavior(ABC):

    @abstractmethod
    def quack(self):
        pass

class Quack(QuackBehavior):

    def quack(self):
        print('鸭子呱呱叫')

class Squeak(QuackBehavior):

    def quack(self):
        print('橡皮鸭子呱呱叫')

class MuteQuack(QuackBehavior):

    def quack(self):
        print('不会叫')

鸭子类

python 复制代码
class Duck:

    def __init__(self):
        self.fly_behavior = None
        self.quack_behavior = None

    def perform_fly(self):
        if self.fly_behavior:
            self.fly_behavior.fly()

    def perform_quack(self):
        if self.quack_behavior:
            self.quack_behavior.quack()

    def swim(self):
        pass

    @abstractmethod
    def display(self):
        pass

整合鸭子的行为

python 复制代码
class MallardDuck(Duck):

    def __init__(self):
        super().__init__()
        self.fly_behavior = FlyWithWings()
        self.quack_behavior = Quack()

    def display(self):
        print("I'm a real Mallard Duck")

测试Duck

python 复制代码
if __name__ == '__main__':
    mallard = MallardDuck()
    mallard.perform_quack()
    mallard.perform_fly()

动态设定行为

python 复制代码
class Duck:
	...

    def set_fly_behavior(self, fly_behavior: FlyBehavior):
        self.fly_behavior = fly_behavior

    def set_quack_behavior(self, quack_behavior: QuackBehavior):
        self.quack_behavior = quack_behavior

class ModelDuck(Duck):

    def __init__(self):
        super().__init__()
        self.fly_behavior = FlyNoWay()
        self.quack_behavior = Quack()

    def display(self):
        print("I'm a model duck")

class FlyRocketPowered(FlyBehavior):
    """利用火箭动力的飞行行为"""

    def fly(self):
        print("I'm flying with a rocket!")

if __name__ == '__main__':

    model = ModelDuck()
    model.perform_fly()
    model.set_fly_behavior(FlyRocketPowered())
    model.perform_fly()

或者换一种方式设置属性,效果一样

python 复制代码
class Duck:

    def __init__(self):
        self._fly_behavior = None
        self._quack_behavior = None

	...

    @property
    def fly_behavior(self):
        return self._fly_behavior

    @fly_behavior.setter
    def fly_behavior(self, fly_behavior: FlyBehavior):
        self._fly_behavior = fly_behavior


    @property
    def quack_behavior(self):
        return self._quack_behavior

    @quack_behavior.setter
    def quack_behavior(self, quack_behavior: QuackBehavior):
        self._quack_behavior = quack_behavior


if __name__ == '__main__':
    model = ModelDuck()
    model.perform_fly()
    model.fly_behavior = FlyRocketPowered()
    # model.set_fly_behavior(FlyRocketPowered())
    model.perform_fly()

完整代码

python 复制代码
from abc import ABC, abstractmethod
from typing import Optional


class FlyBehavior:
    """飞行行为"""

    def fly(self):
        raise NotImplementedError


class FlyWithWings(FlyBehavior):
    """用翅膀飞行"""

    def fly(self):
        print("I'm flying!!")


class FlyNoWay(FlyBehavior):
    """不支持飞行"""

    def fly(self):
        print("I can't fly")


class QuackBehavior(ABC):
    """发出声音行为"""

    @abstractmethod
    def quack(self):
        pass


class Quack(QuackBehavior):

    def quack(self):
        print('鸭子呱呱叫')


class Squeak(QuackBehavior):

    def quack(self):
        print('橡皮鸭子呱呱叫')


class MuteQuack(QuackBehavior):

    def quack(self):
        print('不会叫')


class Duck:

    def __init__(self,
                 fly_behavior: Optional[FlyBehavior] = None,
                 quack_behavior: Optional[QuackBehavior] = None
                 ):
        self._fly_behavior = fly_behavior
        self._quack_behavior = quack_behavior

    def perform_fly(self):
        if self.fly_behavior:
            self.fly_behavior.fly()

    def perform_quack(self):
        if self.quack_behavior:
            self.quack_behavior.quack()

    def swim(self):
        pass

    @abstractmethod
    def display(self):
        pass

    # def set_fly_behavior(self, fly_behavior: FlyBehavior):
    #     self.fly_behavior = fly_behavior
    #
    # def set_quack_behavior(self, quack_behavior: QuackBehavior):
    #     self.quack_behavior = quack_behavior

    @property
    def fly_behavior(self):
        return self._fly_behavior

    @fly_behavior.setter
    def fly_behavior(self, fly_behavior: FlyBehavior):
        self._fly_behavior = fly_behavior


    @property
    def quack_behavior(self):
        return self._quack_behavior

    @quack_behavior.setter
    def quack_behavior(self, quack_behavior: QuackBehavior):
        self._quack_behavior = quack_behavior

class MallardDuck(Duck): # 继承,属于鸭子 IS-A,是一种鸭子的子类型

    def __init__(self):
        super().__init__()
        self.fly_behavior = FlyWithWings() # 组合,拥有飞行行为 HAS-A
        self.quack_behavior = Quack() # 组合,拥有发出声音行为 HAS-A

    def display(self):
        print("I'm a real Mallard Duck")


class ModelDuck(Duck):

    def __init__(self):
        super().__init__()
        self.fly_behavior = FlyNoWay()
        self.quack_behavior = Quack()

    def display(self):
        print("I'm a model duck")


class FlyRocketPowered(FlyBehavior):
    """利用火箭动力的飞行行为"""

    def fly(self):
        print("I'm flying with a rocket!")


if __name__ == '__main__':
    mallard = MallardDuck()
    mallard.perform_quack()
    mallard.perform_fly()

    model = ModelDuck()
    model.perform_fly()
    model.fly_behavior = FlyRocketPowered()
    # model.set_fly_behavior(FlyRocketPowered())
    model.perform_fly()

总结

练习题

python 复制代码
from abc import abstractmethod


class WeaponBehavior:
    """武器行为"""

    @abstractmethod
    def use_weapon(self):
        """使用武器"""
        pass


class KnifeBehavior(WeaponBehavior):
    def use_weapon(self):
        return '匕首'


class BowAndArrowBehavior(WeaponBehavior):
    def use_weapon(self):
        return '弓箭'


class AxeBehavior(WeaponBehavior):
    def use_weapon(self):
        return '斧头'


class SwordBehavior(WeaponBehavior):
    def use_weapon(self):
        return '宝剑'


class Character:
    """人物"""

    def __init__(self, w: WeaponBehavior = None):
        self._weapon = w

    @property
    def weapon(self):
        return self._weapon

    @weapon.setter
    def weapon(self, w: WeaponBehavior):
        self._weapon = w

    def fight(self):
        """战斗"""
        if self._weapon is None:
            print(f"{self.__class__.__name__} has no weapon!")
            return

        weapon = self._weapon.use_weapon()
        print(f"{self.__class__.__name__} use {weapon} fight")

    @abstractmethod
    def display(self) -> None:
        pass

class Queen(Character):
    def display(self) -> None:
        print("I'm a Queen")


class King(Character):
    def display(self) -> None:
        print("I'm a King")


class Troll(Character):
    def display(self) -> None:
        print("I'm a Troll")


class Knight(Character):
    def display(self) -> None:
        print("I'm a Knight")


if __name__ == '__main__':
    queen = Queen()
    queen.fight()
    queen.weapon = KnifeBehavior()
    queen.fight()

    king = King(KnifeBehavior())
    king.fight()

    king.weapon = BowAndArrowBehavior()
    king.fight()
相关推荐
钟离墨笺1 小时前
Go语言学习-->编译器安装
开发语言·后端·学习·golang
钟离墨笺2 小时前
Go语言学习-->从零开始搭建环境
开发语言·后端·学习·golang
我是坑货3 小时前
Spring学习笔记:Spring的基于注解的XML的详细配置
笔记·学习·spring
开开心心就好4 小时前
高效视频倍速播放插件推荐
python·学习·游戏·pdf·计算机外设·电脑·音视频
yzx9910135 小时前
Python开发系统项目
人工智能·python·深度学习·django
行云流水剑5 小时前
【学习记录】Element UI导入报错 * element-ui/lib/theme-chalk/index.css in ./src/main.js
css·学习·ui
FreakStudio5 小时前
一文速通 Python 并行计算:12 Python 多进程编程-进程池 Pool
python·嵌入式·面向对象·多进程·并行计算·电子diy
天才测试猿6 小时前
接口自动化测试之pytest接口关联框架封装
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
先做个垃圾出来………7 小时前
Python中使用pandas
开发语言·python·pandas
爱意随风起风止意难平7 小时前
003 flutter初始文件讲解(2)
学习·flutter