聊聊那些专为算法设计的模式——策略模式

AI越来越火热,人工智能已然成风!而人工智能最重要是各种算法,因此机器学习越来越受到追捧,算法越来越被重视。

作为一个算法的研究者,写出一手高级算法当然是令人兴奋的一件事!但你是否有时会有这种感觉:
1. 写的算法很难通用于所有的数据类型!每来一个新类型的数据,又得改一下算法,或新加一个方法来支持这种类型。
2. 有时候多个算法需要灵活组合,甚至每个算法的顺序不一样都会产生不一样的效果;每一种组合都要为其构建一个新算法,即累又麻烦。
3. 算法越来越多,自建的算法库也越来越庞大而难于管理;

这个时候,让你的算法具有更好通用性、拓展性就显得极为重要!因此,你必须要掌握几个重要的设计模式来优化你的代码,解决这些问题。今天就来聊聊那些专为算法设计的模式:策略模式、模板方法模式、访问模式。

策略模式

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

策略模式当属在算法领域中应用最广泛的一种设计模式,它是对算法、规则的一种封装,具有以下的优点:
- 算法(规则)可自由地切换。
- 避免使用多重条件判断。
- 方便拓展和增加新的算法(规则)。

应用案例

假设有这样一个应用场景:

有一Person类,有年龄(age),体重(weight),身高(height)三个属性。现要对Person的一组对象进行排序,但并没有确定根据什么规则来排序,有时需要根据年龄进行排序,有时需要根据身高进行排序,有时可能是根据身高和体重的综合情况来排序,还有可能……

通过对这个应用场景进行分析,我们会发现,这里需要有多种排序算法,而且需要动态地在这几种算法中进行选择,在未来可能还会添加一新的排序规则……

怎样让我们的排序算法更加的灵活,以适应各种各样的排序规则呢?这里我们就要用到策略模式。来,我们一起看一下具体的代码实现吧。

源码示例:

class Person:
    "人类"

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

    def showMysef(self):
        print(self.name + " " + str(self.age) + " years old, " + str(self.weight) + "kg, " + str(self.height) + "m.")

class ICompare:
    "比较算法"

    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(ICompare):
    "通过身高进行排序"

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

class SortPerson:
    "Person的排序类"

    def __init__(self, compare):
        self.__compare = compare

    def sort(self, personList):
        "排序算法,这里采用最简单的冒泡排序"
        n = len(personList)
        for i in range(0, n-1):
            for j in range(0, n-i-1):
                if(self.__compare.comparable(personList[j], personList[j+1]) > 0):
                    tmp = personList[j]
                    personList[j] = personList[j+1]
                    personList[j+1] = tmp
            j += 1
        i += 1

测试代码:

def testSortPerson():
    personList = [
        Person("Tony", 2, 54.5, 0.82),
        Person("Jack", 31, 74.5, 1.80),
        Person("Nick", 54, 44.5, 1.59),
        Person("Eric", 23, 62.0, 1.78),
        Person("Helen", 16, 45.7, 1.60)
    ]
    sorter0 = SortPerson(CompareByAge())
    sorter0.sort(personList)
    print("根据年龄进行排序后的结果:")
    for person in personList:
        person.showMysef()
    print()

    sorter1 = SortPerson(CompareByHeight())
    sorter1.sort(personList)
    print("根据身高进行排序后的结果:")
    for person in personList:
        person.showMysef()

输出结果:

根据年龄进行排序后的结果:
Tony 2 years old, 54.5kg, 0.82m.
Helen 16 years old, 45.7kg, 1.6m.
Eric 23 years old, 62.0kg, 1.78m.
Jack 31 years old, 74.5kg, 1.8m.
Nick 54 years old, 44.5kg, 1.59m.

根据身高进行排序后的结果:
Tony 2 years old, 54.5kg, 0.82m.
Nick 54 years old, 44.5kg, 1.59m.
Helen 16 years old, 45.7kg, 1.6m.
Eric 23 years old, 62.0kg, 1.78m.
Jack 31 years old, 74.5kg, 1.8m.

看到这,一些熟悉Python的同学肯定要吐槽了!Python是一个简洁明了的语言,使用2行代码就能解决的问题(如下面代码),为什么要写上面这一大堆的东西。

from operator import itemgetter,attrgetter

# 使用operator模块根据年龄、身高进行排序
sortedPerons = sorted(personList, key = attrgetter('age'))
sortedPerons1 = sorted(personList, key=attrgetter('height'))

能提出这个问题,说明你一定是带着思考在阅读!之所以还要这么写,出于以下几个原因:
1. 设计模式是一种编译思想,他和语言没有强关联,应当适用于所有面向对象的语言。Python因为语言本身的灵活性和良好的封装性,使得其自带了很多的功能,而其他语言并没有这样的功能。也许你的算法就是用C++或者Java来写的呢!为了让熟悉其他语言的人也能看懂,这里使用了最接近面向对象思维的方式进行实现(即使你熟悉Python也可通过他来学习一种新的思维方式)。
2. 使用Python语言本身的特性,还是难以实现一些特殊的需求,如要根据身高和体重的综合情况来排序(身高和体重的权重分别是0.6和0.4)。用策略模式就可以很方便地实现,只需要增加一个CompareByHeightAndWeight的策略类就可以,如下面代码:

class CompareByHeightAndWeight(ICompare):
    "根据身高和体重的综合情况来排序(身高和体重的权重分别是0.6和0.4)"

    def comparable(self, person1, person2):
        value1 = person1.height * 0.6 + person1.weight * 0.4
        value2 = person2.height * 0.6 + person2.weight * 0.4
        return value1 - value2

更多更有趣的文章

想获得更多更有趣的设计模式吗?一起来阅读以下系列文章吧!

程序源码

https://github.com/luoweifu/PyDesignPattern

引导篇

生活中的设计模式——启程之前,请不要错过我【试读】

基础篇

生活中的监听模式——一坑爹的热水器

生活中的适配模式——身高不够鞋来凑

生活中的状态模式——人有少、壮、老, 水之冰、液、汽

生活中的单例模式——你是我生命的唯一

生活中的职责模式——我的假条去哪了

生活中的中介模式——找房子问中介

生活中的代理模式——帮我拿一下快递

生活中的装饰模式——你想怎么穿就怎么穿

生活中的工厂模式——你要拿铁还是摩卡

生活中的迭代模式——下一个就是你了

生活中的组合模式——自己电脑组装,价格再降三折

生活中的构建模式——你想要一辆车还是一座房

生活中的克隆模式——给你一个分身术

生活中的策略模式——怎么来不重要,人到就行

生活中的命令模式——大闸蟹,走起!

生活中的备忘模式——好记性不如烂笔头

生活中的享元模式——颜料很贵必须充分利用

生活中的外观模式——学妹别慌,学长帮你

生活中的访问模式——一千个读者一千个哈姆雷特

生活中的设计模式——与经典23种设计模式的不解渊源

生活中的设计模式——那些未完待续的设计模式

进阶篇

深入解读过滤器模式——制作一杯鲜纯细腻的豆浆

深入解读对象池技术——共享让生活更便捷

深入解读回调机制——把你技能亮出来

经验篇

谈谈我对设计模式的理解

谈谈我对设计原则的思考

谈谈我对项目重构的看法



关注【SunLogging】
这里写图片描述
长按或扫码二维码,在手机端阅读更多内容

更多更有趣的文章

想获得更多更有趣的设计模式吗?一起来阅读以下系列文章吧!

程序源码

https://github.com/luoweifu/PyDesignPattern

引导篇

生活中的设计模式——启程之前,请不要错过我【试读】

基础篇

生活中的监听模式——一坑爹的热水器

生活中的适配模式——身高不够鞋来凑

生活中的状态模式——人有少、壮、老, 水之冰、液、汽

生活中的单例模式——你是我生命的唯一

生活中的职责模式——我的假条去哪了

生活中的中介模式——找房子问中介

生活中的代理模式——帮我拿一下快递

生活中的装饰模式——你想怎么穿就怎么穿

生活中的工厂模式——你要拿铁还是摩卡

生活中的迭代模式——下一个就是你了

生活中的组合模式——自己电脑组装,价格再降三折

生活中的构建模式——你想要一辆车还是一座房

生活中的克隆模式——给你一个分身术

生活中的策略模式——怎么来不重要,人到就行

生活中的命令模式——大闸蟹,走起!

生活中的备忘模式——好记性不如烂笔头

生活中的享元模式——颜料很贵必须充分利用

生活中的外观模式——学妹别慌,学长帮你

生活中的访问模式——一千个读者一千个哈姆雷特

生活中的设计模式——与经典23种设计模式的不解渊源

生活中的设计模式——那些未完待续的设计模式

进阶篇

深入解读过滤器模式——制作一杯鲜纯细腻的豆浆

深入解读对象池技术——共享让生活更便捷

深入解读回调机制——把你技能亮出来

经验篇

谈谈我对设计模式的理解

谈谈我对设计原则的思考

谈谈我对项目重构的看法



关注【SunLogging】
这里写图片描述
长按或扫码二维码,在手机端阅读更多内容

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付 39.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值