Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何加强Kotlin类之间的关系_Kotlin - Fatal编程技术网

如何加强Kotlin类之间的关系

如何加强Kotlin类之间的关系,kotlin,Kotlin,我是科特林的新手,正在调查什么是不可能的 我有一个用例,如下所示:- interface Request { fun <T> response(data : T): Lazy<Response> } interface Response data class Request1(val request: String) : Request { data class Response1(val output: String) : Response

我是科特林的新手,正在调查什么是不可能的

我有一个用例,如下所示:-

interface Request {
    fun <T> response(data : T): Lazy<Response>
}

interface Response

data class Request1(val request: String) : Request {
    data class Response1(val output: String) : Response
    override fun <T> response(data: T): Lazy<Response> {
        return lazy { Response1(data as String) }
    }
}

data class Request2(val request: Long) : Request {
    data class Response2(val output: Double) : Response
    override fun <T> response(data: T): Lazy<Response> {
        return lazy { Response2(data as Double) }
    }
}
class Controller {
    fun call(request: Request): Lazy<Response> {
        return when (request) {
            is Request1 -> request.response("Testing Data")
            is Request2 -> request.response(Math.PI)
            else -> TODO()
        }
    }
}
interface Request<ResponseData> {
    fun response(data: ResponseData): Lazy<Response>
}

interface Response

sealed class Requests<T> : Request<T> {
    data class Request1(val request: String) : Requests<String>() {
        inner class Response1(val output: String) : Response

        override fun  response(data: String): Lazy<Response> {
            return lazy { Response1(data) }
        }
    }

    data class Request2(val request: Long) : Requests<Double>() {
        inner class Response2(val output: Double) : Response

        override fun response(data: Double): Lazy<Response> {
            return lazy { Response2(data) }
        }
    }
}


class Controller {
    fun <T> call(request: Request<T>): Lazy<Response> {
        return when (request) {
            is Requests.Request1 -> request.response("Testing Data")
            is Requests.Request2 -> request.response(Math.PI)
            else -> TODO()
        }
    }
}
作为一项技术练习,我试图对远程API请求和响应进行建模,并加强它们之间的关系

我的目标是能够在类的顶部以清晰简洁的方式声明请求和响应之间的关系。这将是(1)。记录此类进行的API调用,2)。强制关系,以便Request1只能生成Response1

伪代码:-

Requests {
  Request1 -> Response1   
  Request2 -> Response2
  ...   
  RequestN -> ResponseN
}
我定义了两个接口
请求
响应
,并使用它们如下:-

interface Request {
    fun <T> response(data : T): Lazy<Response>
}

interface Response

data class Request1(val request: String) : Request {
    data class Response1(val output: String) : Response
    override fun <T> response(data: T): Lazy<Response> {
        return lazy { Response1(data as String) }
    }
}

data class Request2(val request: Long) : Request {
    data class Response2(val output: Double) : Response
    override fun <T> response(data: T): Lazy<Response> {
        return lazy { Response2(data as Double) }
    }
}
class Controller {
    fun call(request: Request): Lazy<Response> {
        return when (request) {
            is Request1 -> request.response("Testing Data")
            is Request2 -> request.response(Math.PI)
            else -> TODO()
        }
    }
}
interface Request<ResponseData> {
    fun response(data: ResponseData): Lazy<Response>
}

interface Response

sealed class Requests<T> : Request<T> {
    data class Request1(val request: String) : Requests<String>() {
        inner class Response1(val output: String) : Response

        override fun  response(data: String): Lazy<Response> {
            return lazy { Response1(data) }
        }
    }

    data class Request2(val request: Long) : Requests<Double>() {
        inner class Response2(val output: Double) : Response

        override fun response(data: Double): Lazy<Response> {
            return lazy { Response2(data) }
        }
    }
}


class Controller {
    fun <T> call(request: Request<T>): Lazy<Response> {
        return when (request) {
            is Requests.Request1 -> request.response("Testing Data")
            is Requests.Request2 -> request.response(Math.PI)
            else -> TODO()
        }
    }
}
虽然我的代码的这个版本与原始版本相比有很多优点,但我仍然不满意的一个特性是,每个请求/响应声明仍然非常冗长,例如,它需要5行代码。是否有一种方法可以使每个请求/响应对声明更简洁?例如,占用更少的代码行

更新II

我试图重构上面的密封类,以便在外部密封类中定义重写的函数
response

interface Request<ResponseData> {
    fun response(data: ResponseData): Lazy<Response>
}

interface Response

sealed class Requests<T> : Request<T> {
    data class Request1(val request: String) : Requests<String>() {
        inner class Response1(val output: String) : Response
    }

    data class Request2(val request: Long) : Requests<Double>() {
        inner class Response2(val output: Double) : Response
    }

    override fun response(data: T): Lazy<Response> {
       return lazy { // What implementation goes here??? // }
    }
}
接口请求{
有趣的响应(数据:ResponseData):懒惰
}
界面响应
密封类请求:请求{
数据类Request1(val请求:String):Requests(){
内部类Response1(val输出:String):响应
}
数据类Request2(val请求:Long):Requests(){
内部类Response2(val输出:Double):响应
}
覆盖有趣的响应(数据:T):懒惰{
return lazy{///这里有什么实现??//}
}
}
这种方法可行吗?
如何在外部密封类中引用单个具体的
ResponseN
类?

也许您的示例从实际操作中得到了简化,但我看不到响应接口的用途,或者需要单独的请求实现来实现代码的功能:

data class Request<T>(val request: String, val responseType: KClass<out T>) {
    fun response(data : T) = lazy { data }
}

class Controller {
    fun <T: Any> call(request: Request<T>): Lazy<T> {
        @Suppress("UNCHECKED_CAST")
        return when (request.responseType) {
            String::class -> request.response("Testing Data" as T)
            Double::class -> request.response(Math.PI as T)
            else -> TODO()
        }
    }
}
数据类请求(val请求:字符串,val响应类型:KClass){
有趣的响应(数据:T)=惰性{data}
}
类控制器{
有趣的呼叫(请求:请求):懒惰{
@抑制(“未选中的_CAST”)
返回时间(request.responseType){
String::class->request.response(“测试数据”为T)
Double::class->request.response(Math.PI作为T)
else->TODO()
}
}
}
不过,使用Lazy有点奇怪,因为您正在包装一个预先计算的值

我的目标是能够在类的顶部以清晰简洁的方式声明请求和响应之间的关系。这将是(1)。记录此类进行的API调用,2)。强制关系,以便Request1只能生成Response1

加强关系的一个好方法是分离接口和实现级别。目前,您的接口定义为

interface Request {
    fun <T> response(data : T): Lazy<Response>
}
然后你声明实际的关系

interface Requester1: Requester<Request1, Response1>
interface Requester2: Requester<Request2, Response2>
接口请求者1:请求者
接口请求者2:请求者
此时,您有了一个文件,该文件清楚地传达了关系,而没有任何实现细节

这是您的最终接口代码,它解决了您对1)的请求。记录此类进行的API调用,2)。强制关系,以便Request1只能生成Response1⬇️

interface Response
interface Request

interface Requester {
    fun <in T: Request, out M: Response> request(data : T): Lazy<M>
}

interface Requester1: Requester<Request1, Response1>
interface Requester2: Requester<Request2, Response2>
接口响应
接口请求
接口请求程序{
乐趣请求(数据:T):懒惰
}
接口请求者1:请求者
接口请求者2:请求者

然后,您可以在单独的位置执行该实现,以保持界面干净且易于理解

sealed class Requests {
    data class RequesterImpl1(val request: String) : Requests, Requester1 {
        override fun request(data: Request1): Lazy<Response1> {
            return lazy { Response1(data) }
        }
    }

    data class RequesterImpl2(val request: Long) : Requests, Requester2 {
         override fun request(data: Double2): Lazy<Response2> {
            return lazy { Response2(data) }
        }
    }
}
密封类请求{
数据类RequesterImpl1(val请求:字符串):请求,请求者1{
覆盖乐趣请求(数据:Request1):懒惰{
返回惰性{Response1(数据)}
}
}
数据类RequesterImpl2(val请求:长):请求,请求者2{
覆盖乐趣请求(数据:Double2):懒惰{
返回惰性{Response2(数据)}
}
}
}
另一种方法:

数据类框(val req:T,val rsp:V)
界面相互作用{
val请求:请求
fun exec():框
}
密封类交互:交互{
类交互1(重写val req:字符串):交互{
覆盖fun exec()=框(请求,“按”)
}
类交互2(覆盖val req:Long):交互{
覆盖fun exec()=框(要求,1.0)
}
}
主要内容(){
val interaction1=交互作用。交互作用1(“hi”)
val interaction2=交互作用。交互作用2(42)
println(interaction1.exec())//Box(req=hi,rsp=by)
println(interaction2.exec())//框(req=42,rsp=1.0)
}

这是我目前使用的设计

fun doNothing(): Unit = Unit

interface Interaction<Input, Output> {

    interface Response<Output> : Interaction<Unit, Output> {
        val output: Output
    }

    interface Request<Input, Output> : Interaction<Input, Output> {
        val input: Input
        fun react(output: Output): Response<Output>
    }
}

sealed class Interactions<I, O> : Interaction<I, O> {

    data class RequestOne(override val input: String) : Interaction.Request<String, Long> {
        internal data class ResponseOne(override val output: Long) : Interaction.Response<Long>

        override fun react(output: Long): Interaction.Response<Long> = ResponseOne(output)
    }

    data class RequestTwo(override val input: CustomInput) : Interaction.Request<CustomInput, CustomOutput> {
        internal data class ResponseTwo(override val output: CustomOutput) : Interaction.Response<CustomOutput>

        override fun react(output: CustomOutput): Interaction.Response<CustomOutput> = ResponseTwo(output)
    }

    data class RequestThree(override val input: Unit = doNothing()) : Interaction.Request<Unit, CustomOutputTwo> {
        internal data class ResponseThree(override val output: CustomOutputTwo) : Interaction.Response<CustomOutputTwo>

        override fun react(output: CustomOutputTwo): Interaction.Response<CustomOutputTwo> = ResponseThree(output)
    }

    data class RequestFour(override val input: Unit = doNothing()) : Interaction.Request<Unit, Unit> {
        internal data class ResponseFour(override val output: Unit = doNothing()) : Interaction.Response<Unit>

        override fun react(output: Unit): Interaction.Response<Unit> = ResponseFour()
    }

    data class RequestFive(override val input: CustomInputTwo) : Interaction.Request<CustomInputTwo, Unit> {
        internal data class ResponseFive(override val output: Unit = doNothing()) : Interaction.Response<Unit>

        override fun react(output: Unit): Interaction.Response<Unit> = ResponseFive()
    }
}
fundoothing():单位=单位
界面相互作用{
界面响应:交互{
val输出:输出
}
接口请求:交互{
val输入:输入
乐趣反应(输出:输出):响应
}
}
密封类交互:交互{
数据类RequestOne(覆盖val输入:字符串):Interaction.Request{
内部数据类ResponseOne(覆盖val输出:Long):Interaction.Response
override-fun-react(输出:长):Interaction.Response=ResponseOne(输出)
}
数据类RequestTwo(覆盖val输入:CustomInput):交互。请求{
内部数据类responseWO(覆盖val输出:CustomOutput):交互。响应
override fun react(输出:CustomOutput):Interaction.Response=responsewo(输出)
}
数据类RequestThree(覆盖val输入:Unit=doNothing()):Interaction.Request{
内部数据类ResponseThree(覆盖val输出:CustomOutputWO):交互。响应
override fun react(输出:CustomOutputWO):交互。响应=响应树(输出)
}
数据类请求