策略模式

1. 定义

定义一系列算法,将每个算法都封装起来,并且使它们之间可以相互替换。策略模式使算法可以独立于使用它的用户而变化

2. 核心思想

对算法、规则进行封装,使得替换算法和新增算法更加灵活

3. 模型说明

3.1 设计要点

策略模式中主要有三个角色,在设计策略模式时要找到并区分这些角色。

(1)上下文环境(Context)​:起着承上启下的封装作用,屏蔽上层应用对策略(算法)的直接访问,封装可能存在的变化。

(2)策略的抽象(Strategy)​:策略(算法)的抽象类,定义统一的接口,规定每个子类必须实现的方法。

(3)具备的策略:策略的具体实现者,可以有多个不同的(算法或规则)实现。

3.2策略模式的优缺点

优点

(1)算法(规则)可自由切换。

(2)避免使用多重条件判断。

(3)方便拓展和增加新的算法(规则)​。

缺点:

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

4. 示例代码

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

from abc import ABCMeta, abstractmethod


class Person(object):
def __init__(self, name, age, height, weight):
self.name = name
self.age = age
self.height = height
self.weight = weight

def show_myself(self):
print(f"my name is {self.name}, i am {self.age} years old, {self.height} cm, {self.weight} kg")


class ICompare(metaclass=ABCMeta):

@abstractmethod
def comparable(self, person1, person2):
pass


class CompareByAge(ICompare):
def comparable(self, person1, person2):
return person1.age - person2.age


class CompareByHeight(ICompare):
def comparable(self, person1, person2):
return person1.height - person2.height


class CompareByWeight(ICompare):
def comparable(self, person1, person2):
return person1.weight - person2.weight


class SortPerson(object):
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


if __name__ == "__main__":
persons = [
Person('lzk', 33, 180, 55),
Person('haha', 20, 170, 50),
Person('gaga', 31, 173, 45),
Person('meimei', 50, 162, 70),
]
age_sort = SortPerson(CompareByAge())
age_sort.sort(persons)
print("*" * 60)
print(f"根据年龄排序:")
for person in persons:
person.show_myself()

print("*" * 60)
height_sort = SortPerson(CompareByHeight())
height_sort.sort(persons)
print(f"根据体重排序:")
for person in persons:
person.show_myself()

输出:
************************************************************
根据年龄排序:
my name is haha, i am 20 years old, 170 cm, 50 kg
my name is gaga, i am 31 years old, 173 cm, 45 kg
my name is lzk, i am 33 years old, 180 cm, 55 kg
my name is meimei, i am 50 years old, 162 cm, 70 kg
************************************************************
根据体重排序:
my name is meimei, i am 50 years old, 162 cm, 70 kg
my name is haha, i am 20 years old, 170 cm, 50 kg
my name is gaga, i am 31 years old, 173 cm, 45 kg
my name is lzk, i am 33 years old, 180 cm, 55 kg