用程序模拟生活
随着社会的发展,时代的进步,出行的方式很多,地铁、快速公交、滴滴打车、共享单车等等,采用什么样的方式出行并不重要,重要的选择那种出现方式能准时到达目的地。
代码:
from abc import ABCMeta, abstractmethodclass IVehicle(metaclass=ABCMeta):"""交通工具的抽象类"""@abstractmethoddef running(self):passclass 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 = nameself.__vechicle = vechicledef 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, abstractmethodclass Person:"""人类"""def __init__(self, name, age, weight, height):self.name = nameself.age = ageself.weight = weightself.height = heightdef show_myself(self):print("%s 年龄: %d 岁, 体重: %0.2fkg, 身高: %0.2fm" % (self.name, self.age, self.weight, self.height))class ICompare(metaclass=ABCMeta):"""比较算法"""@abstractmethoddef comparable(self, person1, person2):"person1 > person2 返回值 大于0, person1 == person2 返回0 person1 < person2 返回小于0"passclass ComparableByAge(ICompare):"""通过年龄排序"""def comparable(self, person1, person2):return person1.age - person2.ageclass ComparaByHeight(ICompare):"""按身高排序"""def comparable(self, person1, person2):return person1.height - person2.heightclass ComparaByWeight(ICompare):"""按身高排序"""def comparable(self, person1, person2):return person1.weight - person2.weightclass SortPerson:"""Person排序类"""def __init__(self, compare):self.__compare = comparedef 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] = tmpj += 1i += 1def 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.设计程序接口时希望部分内部实现由调用方自己实现。
