Posts 设计模式-策略模式
Post
Cancel

设计模式-策略模式

概念解析

策略模式,在于将每个算法都封装起来,并且使它们之间可以相互替换,策略模式可以使算法可以独立使用它的用户而发生变化。其设计模式中的三个角色在于:

  • 上下文环境(Context):起着承上启下的封装作用,屏蔽上层应用对策略(算法)的直接访问,封装可能存在的变化
  • 策略的抽象(Strategy):策略(算法)的抽象类,定义统一 的接口,规定每个子类型需要实现的方法
  • 具备的策略:策略的具体实现者,可以有多个不同的算法以及规则实现

策略模式类图如下:

img

策略模式的优点:

  • 算法/规则可以自由切换
  • 避免使用多重条件进行判断
  • 方便拓展和增加新的算法(规则)

缺点:

  • 所有策略类都需要对外暴露

可适用的场景:

  • 系统中存在很多类,之间的区别在于其不同的行为/策略,则可以采用策略模式动态地让一个对象在许多行为中进行选择
  • 设计程序接口时,希望部分内部实现由调用方自己实现

实例分析

基于策略模式简单设计一个比较器:输入为不同人(Person类),具备不同的特性:身高/体重等,需要设计不同的比较器,进行不同维度上的比较(Python层面其实可以基于内置sorted函数实现) 以下提供泛化层面的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from abc import ABCMeta, abstractmethod


class Person():
    """人类"""
    def __init__(self, name, age, weight, height):
        self.name = name
        self.age = age
        self.weight = weight
        self.height = height

    def show_myself(self):
        print("%s 年龄:%d 岁,体重:%0.2f kg,身高: %0.2f m" % (self.name, self.age, self.weight, self.height))


class ICompare(metaclass=ABCMeta):
    """比较算法"""
    @abstractmethod
    def comparable(self, person1, person2):
        "person1 > person2 返回值>0, person1 == person2 返回0,person1 < person2 返回值小于0"
        pass


class CompareByAge(Icompare):
    """通过年龄排序"""
    def comparable(self, person1, person2):
        return person1.age - person2.age


class CompareByHeight(IComparable):
    """通过身高排序"""
    def comparable(self, person1, person2):
        return person1.height - person2.height


class SortPerson():
    """Person的排序类"""
    def __init__(self, compare):
        self.__compare = compare

    def sort(self, person_list):
        """排序算法
        这里采用最采用的冒泡排序"""
        n = len(person_list)
        for i in range(0, n-1):
            for j in range(0, n-i-1):
                if self.__compare.comparable(person_list[j], person_list[j+1]) > 0:
                    tmp = person_list[j]
                    person_list[j] = person_list[j + 1]
                    person_list[j + 1] = tmp
This post is licensed under CC BY 4.0 by the author.

设计模式-适配模式

设计模式-工厂模式