用程序模拟生活
随着社会的发展,时代的进步,出行的方式很多,地铁、快速公交、滴滴打车、共享单车等等,采用什么样的方式出行并不重要,重要的选择那种出现方式能准时到达目的地。
代码:
from abc import ABCMeta, abstractmethod
class IVehicle(metaclass=ABCMeta):
"""交通工具的抽象类"""
@abstractmethod
def running(self):
pass
class SharedBicycle(IVehicle):
"""共享单车"""
def running(self):
print("骑共享单车(轻快便捷)", end="")
class ExpressBus(IVehicle):
"""快速公交车"""
def running(self):
print("坐快速公交车(绿色环保)", end="")
class Express(IVehicle):
"""快车"""
def running(self):
print("打快车(快速便捷)", end="")
class Subway(IVehicle):
"""地铁"""
def running(self):
print("坐地铁(安全高效)", end="")
class Classmate:
"""来聚餐的同学"""
def __init__(self, name, vechicle):
self.__name = name
self.__vechicle = vechicle
def attend_the_dinner(self):
print(self.__name + " ", end="")
self.__vechicle.running()
print(" 来聚餐! ")
def test_the_dinner():
shared_bicycle = SharedBicycle()
joe = Classmate("Joe", shared_bicycle)
joe.attend_the_dinner()
subway = Subway()
helen = Classmate("Helen", subway)
helen.attend_the_dinner()
express_bus = ExpressBus()
henry = Classmate("Henry", express_bus)
henry.attend_the_dinner()
express = Express()
ruby = Classmate("Ruby", express)
ruby.attend_the_dinner()
if __name__ == '__main__':
test_the_dinner()
什么是策略模式
定义一系列的算法,将每个算法都封装起来,并且使它们之间可以相互替换,策略模式使算法可以独立于使用它的用户变化。
策略模式设计思想
将不同的出行方式理解成一种出行算法,将这些算法抽象出一个基类IVehicle,并定义一系列算法、SharedBicycle 、ExpressBus、Express、Subway。我们可以选择任意种出行方式,并且可以方便地更换出行方式。
策略模式的核心思想是:对算法、规则进行封装,使得替换算法和新增算法更加灵活。
模型说明
策略模式中的主要有三个角色,在设计策略模式时要找到并区分角色。
1.上下文环境:起着承上启下的作用,屏蔽上层应用对策略的直接访问,封装可能存在变化。
2.策略抽象:策略(算法)的抽象类,定义统一的接口,规定每个子集类必须实现算法。
3.具备的策略: 策略的具体实现者,可以有多个不同的实现。
策略模式的优缺点
优点:
1.算法可以自由切换
2.避免使用多重条件判断
3.方便拓展和增加的算法
缺点:
1.所有算法策略的类都对外暴露。
实战
有一个Person类,有年龄(age)、身高(height)、体重(weight)三个属性。现在要对Person类的一组对象进行排序,但并没有确定用什么规则来排序,有时需要根据年龄进行排序,有时需要根据身高排序….
代码
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.2fkg, 身高: %0.2fm" % (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 ComparableByAge(ICompare):
"""通过年龄排序"""
def comparable(self, person1, person2):
return person1.age - person2.age
class ComparaByHeight(ICompare):
"""按身高排序"""
def comparable(self, person1, person2):
return person1.height - person2.height
class ComparaByWeight(ICompare):
"""按身高排序"""
def comparable(self, person1, person2):
return person1.weight - person2.weight
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
j += 1
i += 1
def test_sort_person():
person_list = [
Person("Tony", 2, 54.5, 0.82),
Person("Jack", 31, 74.5, 1.82),
Person("Nick", 54, 44.5, 1.59),
Person("Eric", 23, 62.5, 1.72),
Person("Helen", 16, 45.5, 1.60),
]
print("根据年龄排序")
age_sort = SortPerson(ComparableByAge())
age_sort.sort(person_list)
for person in person_list:
person.show_myself()
print("根据身高排序")
height_sort = SortPerson(ComparaByHeight())
height_sort.sort(person_list)
for person in person_list:
person.show_myself()
print("根据体重排序")
weight_sort = SortPerson(ComparaByWeight())
weight_sort.sort(person_list)
for person in person_list:
person.show_myself()
if __name__ == '__main__':
test_sort_person()
应用场景
1.如果系统里面有许多类,它们之间的区别仅在于有不同行为,那么可以使用策略模式动态地让一个对象在许多行为中选择一个。
2.一个系统需要动态地在几种算法中选择一种。
3.设计程序接口时希望部分内部实现由调用方自己实现。