如何在Kotlin中实现模板方法设计模式?

Mar*_*dik 6 java design-patterns kotlin

考虑一下问题:

我们有一个Base抽象方法的类.现在,我们希望强制执行此方法的每个覆盖都将执行一些参数检查或其他一些苦差事.我们希望这个参数检查在所有覆盖中都是相同的.一种解决方案是将此行为包装在一个非抽象方法中,该方法调用一个抽象方法:

abstract class Base
{
    fun computeSomething(argument: Int): Int
    {
        require(argument > 0) // Some intricate checking
        return execute(argument)
    }

    // Pure functionality, assuming correct arguments
    // Ideally, this would be private. 
    protected abstract fun execute(validArgument: Int): Int
}

class Derived1: Base()
{
    override fun execute(validArgument: Int): Int =
        validArgument * validArgument
}

class Derived2: Base()
{
    override fun execute(validArgument: Int): Int =
        validArgument * validArgument * validArgument
}


fun main(args: Array<String>)
{
    val d = Derived1()
    println(d.computeSomething(23))
}
Run Code Online (Sandbox Code Playgroud)

我想Base::execute私有,这样没有子类Base可以在不检查其参数的情况下偶然调用它.不幸的是,这是不可能的:

错误:(9,5)Kotlin:修饰符'private'与'abstract'不兼容

Kotlin protected比Java更好protected,因为它使函数只能访问子类,但理想情况仍然如此private.

那么有没有一种正确的方法来实现这种模式?另外,出于好奇,是语言设计的不兼容性privateabstract有意识的选择?

小智 2

函数被重写是没有意义的,但不能从该类调用。通过重写该函数,您拥有它的实现,因此可以调用它。

您可以通过将执行逻辑与派生类分离来完成您想要的任务,这可以通过以下几种方式完成:

  • 您可以使用 lambda,并将其传递给Base
  • 您可以创建一个处理执行逻辑的接口实现

通过将它们传递给Base类的构造函数,您将它们的所有权转移给该类。