• 策略模式——设计模式


    一、定义

    策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

    在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等,超市促销可以采用打折、送商品、送积分等方法。

    在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。

    如果使用多重条件转移语句实现(即硬编码),不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。如果采用策略模式就能很好解决该问题。

    二、优缺点

    1.策略模式的主要优点

    1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
    2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
    3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
    4. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
    5. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。


    2.其主要缺点如下

    1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
    2. 策略模式造成很多的策略类,增加维护难度。

    三、代码实现

    1. //用策略模式实现计算器加减乘除
    2. enum class OperationStr {
    3. Plus,
    4. Subtraction,
    5. Multiplication,
    6. Division
    7. }
    8. interface Operation {
    9. fun calculation(var1: Double, var2: Double): Double
    10. }
    11. class PlusOperation : Operation {
    12. override fun calculation(var1: Double, var2: Double) = var1 + var2
    13. }
    14. class SubtractionOperation : Operation {
    15. override fun calculation(var1: Double, var2: Double) =
    16. (var1 - var2).takeIf { var1 - var2 >= 0 } ?: throw IllegalArgumentException()
    17. }
    18. class MultiplicationOperation : Operation {
    19. override fun calculation(var1: Double, var2: Double) = var1 * var2
    20. }
    21. class DivisionOperation : Operation {
    22. override fun calculation(var1: Double, var2: Double) =
    23. if (var1 != 0.0) var1 / var2 else throw IllegalArgumentException()
    24. }
    25. //由初始化来决定具体要执行哪一种策略
    26. class OperationContext(private val operation: Operation) {
    27. fun executeStrategy(num: Double, num2: Double) = operation.calculation(num, num2)
    28. }
    29. //算法控制器
    30. class Calculator {
    31. fun selectOperation(operation : OperationStr) : OperationContext {
    32. val selectedOperation = when (operation) {
    33. OperationStr.Plus -> PlusOperation()
    34. OperationStr.Subtraction -> SubtractionOperation()
    35. OperationStr.Multiplication -> MultiplicationOperation()
    36. OperationStr.Division -> DivisionOperation()
    37. }
    38. return OperationContext(selectedOperation)
    39. }
    40. }
    41. fun main() {
    42. //假设使用计算器是用的数
    43. val num1 = 1.0
    44. val num2 = 1.0
    45. val calculator : Calculator = Calculator()
    46. //选择加法
    47. println(calculator.selectOperation(OperationStr.Plus).executeStrategy(num1, num2))
    48. //选择了减法
    49. println(calculator.selectOperation(OperationStr.Subtraction).executeStrategy(num1, num2))
    50. //选择了乘法
    51. println(calculator.selectOperation(OperationStr.Multiplication).executeStrategy(num1, num2))
    52. //选择了除法
    53. println(calculator.selectOperation(OperationStr.Division).executeStrategy(num1, num2))
    54. }

  • 相关阅读:
    SpringCloud学习笔记(三)
    【祝福伟大的祖国】Java Web 9.2 Request 对象 9.2.2 Request 获取请求数据
    Sourcetree的实际使用开发笔记
    cocos入门7:cocos creator 中的ui系统
    使用 MAUI 在 Windows 和 Linux 上绘制 PPT 的图表
    为SecureCRT配置密钥验证,实现免密登录远程Linux服务器
    TortoiseGit使用教程
    Docker consul
    Day04 Spring和SpringBoot
    C++——string常用接口模拟实现
  • 原文地址:https://blog.csdn.net/m0_37707561/article/details/125541601