Kotlin~策略模式+简单工厂模式消除if else

背景

本文主要介绍策略模式,及如何结合简单工厂优化代码。

策略模式

定义

定义一系列的算法或判断逻辑,将算法或判断逻辑封装起来,让它们可以相互替换,让算法或判断逻辑独立于客户。

核心定义接口,将公共行为抽象起来,具体的逻辑又封装到不同的策略类中。

组成

抽象策略类、具体策略类、上下文场景类

优缺点

优点:

  • 可以动态修改对象的行为

  • 避免使用多重条件选择语句

缺点:

  • 客户端必须知道所有的策略类,并自行决定使用哪个策略类

  • 策略模式将造成产生很多策略类

使用场景

  • 系统需要快速切换算法或动作或系统中有一些类仅仅行为不同。

  • 存在多重条件选择语句时。

示例

下面以钉钉员工请假为例子举例

/**
 * 请假表单
 */
data class LeaveForm(
    val employee: Employee,
    val days: Int,
    val reason: String,//请假原因
    val type: Int // 类型:0病假,1婚丧假,2年假
)

/**
 * 员工
 */
data class Employee(
    val name: String,
    val level: Int
)
interface AuditStrategy {
    // 判断条件是否匹配
    fun isSupport(form: LeaveForm):Boolean

    // 审核业务逻辑
    fun audit(form: LeaveForm)

    // 规则冲突时的优先级
    val priority: Int

    // 规则名称
    val name: String
}
class AuditStrategyImpl1 : AuditStrategy {
    override fun isSupport(form: LeaveForm): Boolean {
        return form.days <= 3 && form.type == 1
    }

    override fun audit(form: LeaveForm) {
        println("form:$form")
        println("三天以下丧假无需审批,自动通过")
    }

    override val priority: Int = 0
    override val name: String = "三天以下丧假"
}
/**
 * 策略工厂类
 *
 */
object AuditStrategyFactory {

    private val auditStrategyList = ArrayList<AuditStrategy>()

    init {
        auditStrategyList.add(AuditStrategyImpl1())
        auditStrategyList.add(AuditStrategyImpl2())
        auditStrategyList.add(AuditStrategyImpl3())
        auditStrategyList.add(AuditStrategyImpl4())
        auditStrategyList.add(AuditStrategyImpl5())
    }

    fun getAuditStrategy(form: LeaveForm): AuditStrategy? {
        var auditStrategy: AuditStrategy? = null
        for (strategy in auditStrategyList) {
            if (strategy.isSupport(form)) {
                if (auditStrategy == null) {
                    auditStrategy = strategy
                } else {
                    // 如果发现优先级相同的其他策略,直接抛出异常
                    if (strategy.priority == auditStrategy.priority) {
                        throw RuntimeException("[${auditStrategy.name}]:[${strategy.name}] 优先级相同")
                    }
                    // 如果有更高的优先级,替代现有规则
                    else if (strategy.priority > auditStrategy.priority) {
                        auditStrategy = strategy
                    }
                }
            }
        }
        return auditStrategy
    }
}

代码重构时,需要先抽象接口或类,然后编写静态工厂。最后实现各个策略,最后将各个策略添加进来。

class LeaveServiceOld {

    // 审核
    fun audit(leaveForm: LeaveForm) {
        when {
            (leaveForm.days <= 3 && leaveForm.type == 1) -> {
                println("三天以下丧家无需审批,自动通过")
            }

            (leaveForm.days > 3 && leaveForm.type == 1) -> {
                println("三天以上丧家,需上级审批")
            }

            (leaveForm.employee.level == 9) -> {
                println("总经理请假无需审批,自动通过")
            }

            (leaveForm.days == 1 && leaveForm.type == 0) -> {
                println("一天病假无需审批,自动通过")
            }

            (leaveForm.days > 1 && leaveForm.type == 0) -> {
                println("一天以上病假,需上级审批")
            }
        }
    }
}

fun main() {
    val service = LeaveServiceOld()
    val employee = Employee("张三", 9)
    val form = LeaveForm(employee, 4, "生病了", 3)
    service.audit(form)

    val factory = AuditStrategyFactory.getAuditStrategy(form)
    factory?.audit(form)
}

总结

静态工厂方法(简单工厂模式)严格来说不能属于设计模式,策略模式不能消除if else,但可以结合静态工厂方法结合去除代码中的if else。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会画板子的物联网工程师

如果文章还不错,欢迎点赞收藏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值