重学设计模式之策略模式(Kotlin)

510 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第二十九天,点击查看活动详情

重学设计模式之策略模式(Kotlin)

前言

策略模式(Strategy Pattern)属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
其主要目的是通过定义相似的算法,替换if else 语句写法,并且可以随时相互替换

适用场景

  1. 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为

  2. 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现

  3. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立

策略模式的角色以及职责

  • 环境角色(Context):持有一个策略类的引用,提供给客户端使用

  • 抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口

  • 具体策略角色(ConcreteStrategy):包装了相关的算法或行为

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9OdE81c2lhbEpaR3AzRlVHa2t3cTRYdVRpY3FrdDVScU9raWM0aHRiS3RiWENoMVZqSmlhamtkVFAwUFVSYjVSRVl2UWVYdUFFdHc5dUxYbkJnVEFlT0ZvVkEvNjQw.png

示例

在日常生活中商场在不同节日会有不同的促销活动,那么我们就以这个场景为例来看看使用策略模式如何实现:

  1. 创建抽象策略角色PromotionStrategy:
//促销接口
interface IPromotionStrategy {
    /**
     * 促销活动
     */
    fun doPromotion()
}
  1. 创建抽象策略角色
  • 618活动促销:
//618活动策略
class Promotion618: IPromotionStrategy{
    override fun doPromotion() {
        System.out.printf("618活动,商品全部8.8折");
    }
}
  • 双十一活动促销
//双十一活动策略
class Promotion1111: IPromotionStrategy{
    override fun doPromotion() {
        System.out.printf("双十一活动,商品全部6.6折,再送一位女朋友一天");
    }
}
  • 元旦活动促销
//元旦活动策略
class PromotionNewYear : IPromotionStrategy {
    override fun doPromotion() {
        System.out.printf("元旦活动,商品全部1折!!!!");
    }
}
  1. 创建环境类
class Context(private val strategy: IPromotionStrategy) {

    fun executeStrategy() {
        strategy.doPromotion()
    }

}
  1. 使用Context来查看改变的促销活动
fun main() {
    val context = Context(Promotion618())
    val context2 = Context(Promotion1111())
    val context3 = Context(PromotionNewYear())

    //6.18到了,开始做618活动
    context.executeStrategy()

    //双十一到了,开始做双十一活动
    context2.executeStrategy()

    //元旦到了,开始做元旦活动
    context3.executeStrategy()
}

输出:

618活动,商品全部8.8折
双十一活动,商品全部6.6折,再送一位女朋友一天
元旦活动,商品全部1折!!!!

建造者模式优缺点

优点:

  • 算法可以自由切换

  • 避免使用多重条件判断

  • 扩展性良好

缺点:

  • 策略类会增多

  • 所有策略类都需要对外暴露