• 设计模式(一):策略模式


    书面定义

    策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户

    内容

    我们的目的是设计一个鸭子类,作为其他鸭子的基类

    按照设计原则,应该将经常变更的部分提取出来,独立成为一个部分。

    以鸭子类来说,假如需要设计一个基类,什么地方会是不变的呢?

    1. 鸭子与叫声有关(这里将不会叫也作为会叫的一种)
    2. 鸭子与飞有关(不会飞也作为一种飞)
    3. 鸭子与游泳有关

    所以首先设计一种类:

    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 设计模式》

  • 相关阅读:
    Spring 学习7 -事务
    Spring学习 6- Spring MVC (Spring MVC原理及配置详解)
    看秒杀系统的时候看到的关于并发队列的介绍,摘抄如下
    Spring 学习 3- AOP
    Spring学习-1 框架总览
    Spring 学习 5- task 定时任务
    JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁,
    指定链接的样式的顺序
    css方法实现div固定浏览器底端
    文件中批量搜索字符串
  • 原文地址:https://www.cnblogs.com/hf99/p/10785155.html
Copyright © 2020-2023  润新知