美文网首页
Kotlin Design Pattern: Chain of

Kotlin Design Pattern: Chain of

作者: ParanoidMarvern | 来源:发表于2017-12-17 11:04 被阅读0次

    The chain of responsibility pattern is used to process varied requests, each of which may be dealt with by a different handler.

    Setup

    • Handler: define the interface for handling request, (optional)implements the successor link
    • Concrete Handler: handles the request it is responsible for; can access its successor; if the ConcreteHandler can handle this request, then handle it, otherwise it forwards the request to its successor.
    • Client: initiates a request to a ConcreteHandler object on the chain.

    Example 1

    // Step 3: Client code
    fun main(args: Array<String>) {
        val arcSoldiers = ArcSoldiers()
        val swordSoldiers = SwordSoldiers()
        val cookSoldiers = CookSoidlers()
    
        fun orderChain(arcSoldiers: ArcSoldiers,
                       swordSoldiers: SwordSoldiers,
                       cookSoidlers: CookSoidlers): Soldiers{
            arcSoldiers.next = swordSoldiers
            swordSoldiers.next = cookSoidlers
            return arcSoldiers
        }
    
        val soldiers = orderChain(arcSoldiers, swordSoldiers, cookSoldiers)
    
        soldiers.onCall("arrows")
        soldiers.onCall("cook")
        soldiers.onCall("swing")
        soldiers.onCall("cannon")
    }
    
    // Step 1: Define the request interface
    
    interface Soldiers{
        fun onCall(order: String)
    }
    
    // Step 2: ConcreteHandlers to deal with different orders
    
    class ArcSoldiers(var next: Soldiers? = null): Soldiers{
        override fun onCall(order: String) {
            if (order == "arrows")
                println("Aye! Loose the arrows!")
            else
                next?.onCall(order)?: println("General, we are short-handed.")
        }
    }
    
    class SwordSoldiers(var next: Soldiers? = null): Soldiers{
        override fun onCall(order: String) {
            if(order == "swing")
                println("Aye! Swing the swords!")
            else
                next?.onCall(order)?: println("General, we are short-handed.")
        }
    }
    
    
    class CookSoidlers(var next: Soldiers? =null): Soldiers{
        override fun onCall(order: String) {
            if (order == "cook")
                println("Aye! Cook the dinners!")
            else
                next?.onCall(order)?: println("General, we are short-handed.")
        }
    }
    
    /**
            prints
    
            Aye! Loose the arrows!
            Aye! Cook the dinners!
            Aye! Swing the swords!
            General, we are short-handed.
     **/
    

    Example 2

    // Step 3: Client code
    
    fun main(args: Array<String>) {
        val authenticationHeader = AuthenticationHeader("123456")
        val contentTypeHeader = ContentTypeHeader("json")
        val messageBody = BodyPayload("{\"username\"=\"dbacinski\"}")
    
        // Here in 'fun messageChainWithAuthorization()', client could define the successors.
    
        fun messageChainWithAuthorization(authenticationHeader: AuthenticationHeader,
                                          contentTypeHeader: ContentTypeHeader,
                                          messageBody: BodyPayload): MessageChain {
            authenticationHeader.next = contentTypeHeader
            contentTypeHeader.next = messageBody
            return authenticationHeader
        }
    
        val messageChainWithAuthorization = messageChainWithAuthorization(authenticationHeader,
                contentTypeHeader,
                messageBody)
        val messageWithAuthentication = messageChainWithAuthorization.addLines(
                "Message with Authentication:\n")
        println(messageWithAuthentication)
    }
    
    // Step 1: Define the interface for handling request.
    
    interface MessageChain {
        fun addLines(inputHeader: String): String
    }
    
    // Step 2: ConcreteHandler to handle specific request.
    
    class AuthenticationHeader(val token: String?, var next: MessageChain? = null) : MessageChain {
    
        override fun addLines(inputHeader: String): String {
            token ?: throw IllegalStateException("Token should be not null")
            return "$inputHeader Authorization: Bearer $token\n".let { next?.addLines(it) ?: it }
        }
    }
    
    class ContentTypeHeader(val contentType: String, var next: MessageChain? = null) : MessageChain {
    
        override fun addLines(inputHeader: String): String
                = "$inputHeader ContentType: $contentType\n".let { next?.addLines(it) ?: it }
    }
    
    class BodyPayload(val body: String, var next: MessageChain? = null) : MessageChain {
    
        override fun addLines(inputHeader: String): String
                = "$inputHeader $body\n".let { next?.addLines(it) ?: it }
    }
    
    /**
            prints
    
            Message with Authentication:
            Authorization: Bearer 123456
            ContentType: json
            {"username"="dbacinski"}
            **/
    

    NOTE
    Safe call operator '?.' & Elvis operator '?:'

    // Safe call operator  ?.
    
    /**
            foo?.bar()
            in Kotlin is same as
    
            if(foo == null)
                return null;
            else
                return foo.bar();
            in Java
    
            In plain words, if foo is null then returns null, otherwise returns foo.bar()
     **/
    
    // Elvis operator  ?:
    
    /**
            foo?:bar
            in Kotlin is same as
    
            if(foo != null)
                return foo;
            else
                return bar;
            in Java
    
            In plain words, if foo is NOT null, return itself, otherwise it returns the
            value after the elvis operator.
     **/
    
    
    // Combination of safe call operator & elvis operator
    
    /**
            For example
    
            a == b is same as:
    
            a?.equals(b)?:(b === null)
    
            in plain words:
            if a === null, return (b === null), if (b === null), return true;
            if a !== null, return a.equals(b), which is true or false.
    
     **/
    

    相关文章

      网友评论

          本文标题:Kotlin Design Pattern: Chain of

          本文链接:https://www.haomeiwen.com/subject/vtoewxtx.html