移动端访问不佳,请访问我的个人博客

设计模式学习的demo地址,欢迎大家学习交流

策略模式

策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。

策略模式的组成

  • 抽象策略角色(Strategy): 策略类,通常由一个接口或者抽象类实现。
  • 具体策略角色(ConcreteStrategy):包装了相关的算法和行为。
  • 环境角色(Context):持有一个策略类的引用,最终给客户端调用。

策略模式的基本实现

上图是最基本的装饰模式的结构图,下面将用Swift代码来实现一个基本策略模式:

// 策略类,定义所有支持 的算法的公共接口
protocol Strategy {
    func AlgorithmInterface()
}

// 具体策略类,封装了具体的算法或行为,继承于Strategy
class ConcreteStrategyA: Strategy {
    func AlgorithmInterface() {
        print("ConcreteStrategyA")
    }
}

class ConcreteStrategyB: Strategy {
    func AlgorithmInterface() {
        print("ConcreteStrategyB")
    }
}

class ConcreteStrategyC: Strategy {
    func AlgorithmInterface() {
        print("ConcreteStrategyC")
    }
}

// Context上下文,用一个 ConcreteStrategy来配置,维护一个对Strategy对象的引用
class Context {
    var strategy: Strategy?
    func ContextInterface() {
        strategy?.AlgorithmInterface()
    }
}

以上代码是最简单的策略模式的实现过程,定义了一个Strategy的算法族,通过它的子类可以实现算法(AlgorithmInterface)的替换,而不会影响到客户端。

用策略模式解决实际问题(商场打折)

我们知道在商场中一般有很多打折优惠方案,类似这种问题就可以用策略模式来解决,打折不同的方案就相当于不同的策略(ConcreteStrategy),然后用一个Context类来实现不同算法的切换,下面是商场打折策略模式的实现于UML图:

以上是一个简单的商场收银系统,CashNormal为普通收费子类,CashRebate为打折收费子类,CashReturn为返利收费子类,下面是代码的实现过程:

import Foundation

// 定义一个收费的策略接口
protocol CashSuper {
    func acceptCash(money: Double) -> Double
}

// 普通收费子类
class CashNormal: CashSuper {
    // 正常原价返回
    func acceptCash(money: Double) -> Double {
        return money
    }
}

// 打折收费子类
class CashRebate: CashSuper {
    // 折扣率
    private var moneyRebate: Double = 1.0

    init(moneyRebate: Double) {
        self.moneyRebate = moneyRebate
    }

    func acceptCash(money: Double) -> Double {
        return money*moneyRebate
    }
}

// 返利收费子类
class CashReturn: CashSuper {
    // 返利要求
    private var moneyCondition: Double = 0
    // 返多少
    private var moneyReturn: Double    = 0

    init(moneyCondition: Double, moneyReturn: Double) {
        self.moneyCondition = moneyCondition
        self.moneyReturn    = moneyReturn
    }

    func acceptCash(money: Double) -> Double {
        var result = money
        if money >= moneyCondition {
            result = money - floor(money / moneyCondition) * moneyReturn
        }
        return result
    }
}

// context类
class CashContext {
    private var cs: CashSuper?

    // 通过枚举判断使用哪种方式
    init(style: CashStyle) {
        switch style {
        case .normal:
            cs = CashNormal()
        case .rebate(moneyRebate: let money):
            cs = CashRebate(moneyRebate: money)
        case .return(moneyCondition: let moneyCondition, moneyReturn: let moneyReturn):
            cs = CashReturn(moneyCondition: moneyCondition, moneyReturn: moneyReturn)
        }
    }

    func getResult(money: Double) -> Double {
        return cs?.acceptCash(money: money) ?? 0
    }
}

// 优惠的枚举类型
enum CashStyle {
    case normal
    case rebate(moneyRebate: Double)
    case `return`(moneyCondition: Double, moneyReturn: Double)
}

下面我们测试一下代码:

let money: Double = 300
// 普通
let normal = CashContext(style: .normal)
// 打7折
let rebate = CashContext(style: .rebate(moneyRebate: 0.7))
// 满一百返20
let `return` = CashContext(style: .return(moneyCondition: 100, moneyReturn: 20))
print("普通: \(normal.getResult(money: money))")
print("打7折: \(rebate.getResult(money: money))")
print("满一百返20: \(`return`.getResult(money: money))")

下面是执行的结果:

普通: 300.0
打7折: 210.0
满一百返20: 240.0

策略模式总结

我们可以理解为策略就是用来封装算法,但在实践过程中不用那么死板,可以用来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

以上是我对于策略模式的理解,如果有不对的地方欢迎大家交流,最后谢谢大家的阅读~~

swift设计模式学习 - 策略模式的更多相关文章

  1. swift设计模式学习 - 代理模式

    移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 代理模式 代理模式为其他对象提供一种代理以控制对这个对象的访问,在某些情况下,一个对象不适合或者不能直接引用另一个对象 ...

  2. swift设计模式学习 - 原型模式

    移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 原型模式 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 定义 用原型实例指定创建对象的种类,并且通 ...

  3. 设计模式学习——策略模式(Strategy Pattern)

    0. 前言 最近在重构公司的一个项目的时候,在抽取DES加密重复部分代码的时候,突然间想起了策略模式,感觉策略模式好像可以应用上,于是重新学习了下策略模式.注:在DES加密中,有DES和TDES算法, ...

  4. swift设计模式学习 - 模板方法模式

    移动端访问不佳,请访问我的个人博客 设计模式学习的demo地址,欢迎大家学习交流 模板方法模式 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结 ...

  5. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  6. 设计模式学习--复合模式(Compound Pattern)

    设计模式学习--复合模式(Compound Pattern) 概述 ——————————————————————————————————————————————————— 2013年8月4日<H ...

  7. [design-patterns]设计模式之一策略模式

    设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...

  8. 设计模式之策略模式和状态模式(strategy pattern & state pattern)

    本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...

  9. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

随机推荐

  1. kubernetes网络原理

    1.1. 基础原则 每个Pod都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的.扁平的网络空间中,不管是否运行在同一Node上都可以通过Pod的IP来访问. k8s中Pod的IP是最 ...

  2. 【PyQt5-Qt Designer】读取txt文件在打印

    from PyQt5.QtGui import QFont,QTextDocument,QTextCursor from PyQt5.QtWidgets import QApplication, QM ...

  3. Python实现常用的逻辑数据结构

    逻辑数据结构包括:线形结构.树形结构.图形结构.集合:存储结构包括:顺序存储.链式存储.索引存储.散列存储. 同一种逻辑结构可以有四种存储结构,不同的存储结构增.删.查.改的速度不同.逻辑结构与存储结 ...

  4. 泛型T和通配符?的区别

    这里如果是泛型T的话,那么创建该类的时候就需要指定类型,而通配符不需要.

  5. 【Python】【Web.py】python web py入门-5-请求处理(下)

    前面一篇,我们演示了如何获取GET和POST请求的参数信息,这篇我们介绍如何获取请求的头部信息,这个方法我们在前面一篇文章已经给出了.直接来看一个例子,首先,我们在hello.py文件新增一个方法,用 ...

  6. 【小甲鱼】【Python】正则表达式(二)

    >>> import re#|表示或的意思 >>> re.search(r"Fish(C|D)","FishC") < ...

  7. XtraBackup完整备份与增量备份的原理

    MySQL数据库实现备份的操作包括完整备份和增量备份等,本文我们主要介绍一下增量备份和完整备份的原理,接下来我们就一起来了解一下这部分内容. 完整备份的原理: 对于InnoDB,XtraBackup基 ...

  8. 使用spring boot,gradle,idea,js,html创建一个小的前后端程序

    1:配置build.gradle,添加依赖等 buildscript { repositories { mavenCentral() } dependencies { classpath('org.s ...

  9. Linux实验楼学习之三

    查看用户 who am i or who mom likes who 命令其它常用参数 参数 说明 -a 打印能打印的全部 -d 打印死掉的进程 -m 同am i,mom likes -q 打印当前登 ...

  10. 在 Angularjs 中 ui-sref 和 $state.go

    ui-sref 一般使用在 <a>...</a>: <a ui-sref="message-list">消息中心</a> $stat ...