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

设计模式学习的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)
//7let 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实现MD5算法&引入第三方类库MBProgressHUD

    之前项目里面是用objc写的MD5加密算法,最近在用swift重写以前的项目,遇到了这个问题。顺带解决掉的还有如何引入第三方的类库,例如MBProgressHUD等一些特别好的控件解决的方法其实是用objc和swift混合编程的方法,利用Bridging-header文件。你可以简单的理解为在一个用swift语言开发的工程中,引入objective-c文件是需要做的一个串联文件,好比架设了一个桥,让swift中也可以调用objective-c的类库和frame等等。

  2. swift排序算法和数据结构

    vararrayNumber:[Int]=[2,4,216)">6,216)">7,216)">3,216)">8,216)">1]//冒泡排序funcmaopao->[Int]{forvari=0;i

  3. swift - 函数指针的应用 - 避免重复算法

    =nil;})}privatefuncsearch(selector:(Employee->Bool))->[Employee]{varresults=[Employee]();foreinemployees{if(selector(e)){results.append(e);}}returnresults;}}

  4. 如何用 Swift 实现 A* 寻路算法

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. swift算法实践1

    在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法。逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。

  6. swift算法实践2

    字符串hash算法Time33在效率和随机性两方面上俱佳。对于一个Hash函数,评价其优劣的标准应为随机性,即对任意一组标本,进入Hash表每一个单元之概率的平均程度,因为这个概率越平均,数据在表中的分布就越平均,表的空间利用率就越高。Times33的算法很简单,就是不断的乘33,见下面算法原型。

  7. swift算法实践3)-KMP算法字符串匹配

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  8. swift算法实践4)-trie自动机

    1、trie自动机是识别字符串的确定性有向无环自动机2、图示3、构造代码F包括了状态q所对应的P中的字符串

  9. Swift设计模式之策略模式

    转自Swift设计模式原文Design-Patterns-In-Swift

  10. Swift 算法实战之路一

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部