Skip to content

策略模式实现状态校验

在登录校验的场景下,建造者模式可以将每个校验策略当做一个“部件”,通过建造者来逐步构建出一个完整的校验流程。每个部件(策略)可以根据需要进行选择或组合。最终的构建结果是一个包含所选策略的校验器(LoginValidator)。

1. 建造者模式的基本结构

建造者模式包括以下角色:

  • Builder:抽象建造者,定义创建各个部件的接口。
  • ConcreteBuilder:具体建造者,负责实现 Builder 中定义的接口,构建出完整的产品。
  • Product:最终构建的产品,这里是 LoginValidator
  • Director:指挥者,负责调用建造者的接口来构建最终产品。

2. 实现步骤

2.1 定义校验策略接口

我们依然使用 ValidationStrategy 接口来定义校验策略。

kotlin
// 校验策略接口
interface ValidationStrategy {
    fun validate(input: String): Boolean
}

2.2 具体校验策略

具体的校验策略保持不变:

kotlin
class UsernameValidation : ValidationStrategy {
    override fun validate(input: String): Boolean {
        return input.matches("^[a-zA-Z0-9]{3,20}$".toRegex())
    }
}

class PasswordValidation : ValidationStrategy {
    override fun validate(input: String): Boolean {
        return input.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$".toRegex())
    }
}

class CaptchaValidation : ValidationStrategy {
    override fun validate(input: String): Boolean {
        return input.matches("^[0-9]{6}$".toRegex())
    }
}

class EmailValidation : ValidationStrategy {
    override fun validate(input: String): Boolean {
        return input.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$".toRegex())
    }
}

2.3 定义建造者接口

ValidationBuilder 定义了添加校验策略的接口方法。

kotlin
// 校验建造者接口
interface ValidationBuilder {
    fun addUsernameValidation(): ValidationBuilder
    fun addPasswordValidation(): ValidationBuilder
    fun addCaptchaValidation(): ValidationBuilder
    fun addEmailValidation(): ValidationBuilder
    fun build(): LoginValidator
}

2.4 具体建造者实现

DefaultValidationBuilder 是具体的建造者,它会按照特定的顺序和条件构建一个完整的校验器。

kotlin
// 具体建造者
class DefaultValidationBuilder : ValidationBuilder {
    private val strategies = mutableListOf<ValidationStrategy>()

    override fun addUsernameValidation(): ValidationBuilder {
        strategies.add(UsernameValidation())
        return this
    }

    override fun addPasswordValidation(): ValidationBuilder {
        strategies.add(PasswordValidation())
        return this
    }

    override fun addCaptchaValidation(): ValidationBuilder {
        strategies.add(CaptchaValidation())
        return this
    }

    override fun addEmailValidation(): ValidationBuilder {
        strategies.add(EmailValidation())
        return this
    }

    override fun build(): LoginValidator {
        return LoginValidator(strategies)
    }
}

2.5 定义 LoginValidator

LoginValidator 现在不再依赖工厂来创建策略,而是由建造者来负责策略的组合。

kotlin
class LoginValidator(private val strategies: List<ValidationStrategy>) {

    // 校验用户登录信息
    fun validateLogin(username: String, password: String, captcha: String): Boolean {
        val validations = strategies.map { it.validate(username) }
        return validations.all { it }
    }
}

2.6 使用建造者模式

通过使用建造者模式,用户可以根据需求逐步选择要加入的校验策略,而不需要一次性构建所有校验逻辑。

kotlin
fun main() {
    // 使用建造者来构建 LoginValidator
    val loginValidator = DefaultValidationBuilder()
        .addUsernameValidation()
        .addPasswordValidation()
        .addCaptchaValidation()
        .build()

    // 模拟登录信息
    val username = "user123"
    val password = "Password1"
    val captcha = "123456"

    // 执行登录校验
    if (loginValidator.validateLogin(username, password, captcha)) {
        println("登录成功")
    } else {
        println("登录失败")
    }
}

2.7 动态选择校验策略

建造者模式的一个重要优势是,你可以灵活地选择需要的校验策略,而无需更改 LoginValidator 类。

假如用户需要邮箱校验,可以简单地在建造器链中添加 addEmailValidation() 方法:

kotlin
fun main() {
    // 使用建造者来构建支持邮箱校验的 LoginValidator
    val loginValidator = DefaultValidationBuilder()
        .addUsernameValidation()
        .addPasswordValidation()
        .addCaptchaValidation()
        .addEmailValidation()  // 添加邮箱校验
        .build()

    // 模拟登录信息
    val username = "user123"
    val password = "Password1"
    val captcha = "123456"
    val email = "user@example.com"

    // 执行登录校验
    if (loginValidator.validateLogin(username, password, captcha)) {
        println("登录成功")
    } else {
        println("登录失败")
    }
}

3. 优点与总结

  • 模块化和灵活性:每个校验策略都可以单独进行组合和选择,提供了很高的灵活性。例如,用户可以根据需要选择加入邮箱校验、验证码校验等。
  • 清晰的建造过程:通过建造者模式,校验策略的选择和组合过程变得清晰且易于维护。
  • 避免构造函数参数膨胀LoginValidator 的构造函数不再依赖于传入大量的校验策略,而是由建造者来管理这些策略,使得代码结构更加简洁。
  • 扩展性强:若要增加新的校验策略,只需要新增一个 ValidationStrategy 实现类,并在建造者中提供相应的方法。

这种方式让我们能够根据具体需求选择不同的策略组合,具有高度的灵活性和可扩展性,同时避免了修改核心逻辑类 LoginValidator

Released under the MIT License.