第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁(yè) 慕課教程 Kotlin 教程 Kotlin 教程 Kotlin 如何實(shí)現(xiàn)其他常用設(shè)計(jì)模式

Kotlin 如何實(shí)現(xiàn)其他常用設(shè)計(jì)模式

前兩篇文章都詳細(xì)分析了 Kotlin 如何實(shí)現(xiàn)常用的單例、代理設(shè)計(jì)模式。并且從代碼實(shí)現(xiàn)和使用場(chǎng)景分別對(duì)比了 Java 和 Kotlin。那其實(shí)總共有 23 種設(shè)計(jì)模式,不可能每一種都能詳細(xì)介紹,那么這篇文章會(huì)繼續(xù)介紹 Kotlin 實(shí)現(xiàn)其他設(shè)計(jì)模式方法,因?yàn)槠邢蓿粫?huì)特別詳細(xì)對(duì)比 Java 中的實(shí)現(xiàn)。

1. Kotlin 實(shí)現(xiàn)觀察者模式

1.1 模式的介紹

模式定義了指多個(gè)對(duì)象間存在一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。這種模式有時(shí)又稱作發(fā)布 - 訂閱模式、模型 - 視圖模式,它是對(duì)象行為型模式。

1.2 模式的特點(diǎn)

  • 降低了目標(biāo)與觀察者之間的耦合關(guān)系,兩者之間是抽象耦合關(guān)系;
  • 目標(biāo)與觀察者之間建立了一套觸發(fā)機(jī)制;
  • 當(dāng)觀察者對(duì)象很多時(shí),通知的發(fā)布會(huì)花費(fèi)很多時(shí)間,影響程序的效率。

1.3 Kotlin 代碼實(shí)現(xiàn)

Kotlin 實(shí)現(xiàn)觀察者模式可以使用 Kotlin 中內(nèi)置的 by Delegates.observable 代理輕松實(shí)現(xiàn)。

interface TextChangedListener {
    fun onTextChanged(oldText: String, newText: String)
}

class PrintingTextChangedListener : TextChangedListener {
    
    private var text = ""
    
    override fun onTextChanged(oldText: String, newText: String) {
        text = "Text is changed: $oldText -> $newText"
    }
}

class TextView {

    val listeners = mutableListOf<TextChangedListener>()

    var text: String by Delegates.observable("") { _, old, new ->
        listeners.forEach { it.onTextChanged(old, new) }
    }
}

fun main() {
  val textView = TextView().apply {
      listener = PrintingTextChangedListener()
  }

  with(textView) {
     text = "old text"
     text = "new text"
  }
}

2. Kotlin 實(shí)現(xiàn)策略模式

2.1 模式的介紹

該模式定義了一系列算法,并將每個(gè)算法封裝起來(lái),使它們可以相互替換,且算法的變化不會(huì)影響使用算法的客戶。策略模式屬于對(duì)象行為模式,它通過(guò)對(duì)算法進(jìn)行封裝,把使用算法的責(zé)任和算法的實(shí)現(xiàn)分割開(kāi)來(lái),并委派給不同的對(duì)象對(duì)這些算法進(jìn)行管理。

2.2 模式的特點(diǎn)

  • 使用策略模式可以避免使用多重條件語(yǔ)句,如 if…else 語(yǔ)句、switch…case 語(yǔ)句;
  • 提供了一系列的可供重用的策略實(shí)現(xiàn),適合使用繼承可以把公共代碼轉(zhuǎn)移到父類里面,從而避免重復(fù)的代碼;
  • 提供了對(duì)開(kāi)閉原則的完美支持,可以在不修改原代碼的情況下,靈活增加新策略實(shí)現(xiàn);
  • 策略模式會(huì)新增很多的策略類,增加維護(hù)難度。

2.3 Kotlin 代碼實(shí)現(xiàn)

class Printer(private val stringFormatterStrategy: (String) -> String) {
    fun printString(string: String) {
        println(stringFormatterStrategy(string))
    }
}

val lowerCaseFormatter: (String) -> String = { it.toLowerCase() }
val upperCaseFormatter = { it: String -> it.toUpperCase() }

fun main() {
  val inputString = "Something input"
  val lowerCasePrinter = Printer(lowerCaseFormatter)
  lowerCasePrinter.printString(inputString)
  
  val upperCasePrinter = Printer(upperCaseFormatter)
  upperCasePrinter.printString(inputString)

  val prefixPrinter = Printer { "Prefix: $it" }
  prefixPrinter.printString(inputString)
}

3. Kotlin 實(shí)現(xiàn)狀態(tài)模式

3.1 模式的介紹

該模式定義了對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的 “判斷邏輯” 提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。

3.2 模式的特點(diǎn)

  • 狀態(tài)類職責(zé)明確,有利于程序的擴(kuò)展。通過(guò)定義新的子類很容易地增加新的狀態(tài)和轉(zhuǎn)換;
  • 結(jié)構(gòu)清晰,狀態(tài)模式將與特定狀態(tài)相關(guān)的行為局部化到一個(gè)狀態(tài)中,并且將不同狀態(tài)的行為分割開(kāi)來(lái),符合 “單一職責(zé)原則”;
  • 不同的狀態(tài)引入獨(dú)立的對(duì)象中會(huì)使得狀態(tài)轉(zhuǎn)換變得更加明確,且減少對(duì)象間的相互依賴;
  • 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)的類與對(duì)象的個(gè)數(shù)。

3.3 Kotlin 代碼實(shí)現(xiàn)

sealed class AuthorizationState

object Unauthorized : AuthorizationState()

class Authorized(val userName: String) : AuthorizationState()

class AuthorizationPresenter {

    private var state: AuthorizationState = Unauthorized

    val isAuthorized: Boolean
        get() = when (state) {
            is Authorized -> true
            is Unauthorized -> false
        }

    val userName: String
        get() {
            val state = this.state
            return when (state) {
                is Authorized -> state.userName
                is Unauthorized -> "Unknown"
            }
        }

    fun loginUser(userName: String) {
        state = Authorized(userName)
    }

    fun logoutUser() {
        state = Unauthorized
    }

    override fun toString() = "User '$userName' is logged in: $isAuthorized"
}

fun main() {
   val authorizationPresenter = AuthorizationPresenter()
   authorizationPresenter.loginUser("admin")
   println(authorizationPresenter)
   authorizationPresenter.logoutUser()
   println(authorizationPresenter)
}

4. Kotlin 實(shí)現(xiàn) Builder 模式

4.1 模式的介紹

該模式定義了將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。它是將一個(gè)復(fù)雜的對(duì)象分解為多個(gè)簡(jiǎn)單的對(duì)象,然后一步一步構(gòu)建而成。它將變與不變相分離,即產(chǎn)品的組成部分是不變的,但每一部分是可以靈活選擇的。

4.2 模式的特點(diǎn)

  • 擴(kuò)展性好,各個(gè)具體的建造者相互獨(dú)立,有利于解耦。
  • 封裝性好,構(gòu)建和表示分離。
  • 隱藏產(chǎn)品內(nèi)部組成的細(xì)節(jié),可以對(duì)創(chuàng)建過(guò)程逐步細(xì)化,而不對(duì)其它模塊產(chǎn)生任何影響。
  • 內(nèi)部變化復(fù)雜,如果產(chǎn)品內(nèi)部發(fā)生變化,則建造者也要同步修改,維護(hù)成本較大。

4.3 Kotlin 代碼實(shí)現(xiàn)

class Dialog {

    fun showTitle() = println("showing title")

    fun setTitle(text: String) = println("setting title text $text")

    fun setTitleColor(color: String) = println("setting title color $color")

    fun showMessage() = println("showing message")

    fun setMessage(text: String) = println("setting message $text")

    fun setMessageColor(color: String) = println("setting message color $color")

    fun showImage(bitmapBytes: ByteArray) = println("showing image with size ${bitmapBytes.size}")

    fun show() = println("showing dialog $this")
}

class DialogBuilder() {
    constructor(init: DialogBuilder.() -> Unit) : this() {
        init()
    }

    private var titleHolder: TextView? = null
    private var messageHolder: TextView? = null
    private var imageHolder: File? = null

    fun title(init: TextView.() -> Unit) {
        titleHolder = TextView().apply { init() }
    }

    fun message(init: TextView.() -> Unit) {
        messageHolder = TextView().apply { init() }
    }

    fun image(init: () -> File) {
        imageHolder = init()
    }

    fun build(): Dialog {
        val dialog = Dialog()

        titleHolder?.apply {
            dialog.setTitle(text)
            dialog.setTitleColor(color)
            dialog.showTitle()
        }

        messageHolder?.apply {
            dialog.setMessage(text)
            dialog.setMessageColor(color)
            dialog.showMessage()
        }

        imageHolder?.apply {
            dialog.showImage(readBytes())
        }

        return dialog
    }

    class TextView {
        var text: String = ""
        var color: String = "#00000"
    }
}

fun dialog(init: DialogBuilder.() -> Unit): Dialog {
    return DialogBuilder(init).build()
}

fun main() {
   val dialog: Dialog = dialog {
	title {
    	text = "Dialog Title"
    }
    message {
        text = "Dialog Message"
        color = "#333333"
    }
    image {
        File.createTempFile("image", "jpg")
    }
  }
  dialog.show()
}

5. Kotlin 實(shí)現(xiàn)工廠方法模式

5.1 模式的介紹

該模式實(shí)際上是對(duì)簡(jiǎn)單工廠模式的進(jìn)一步抽象化,其好處是可以使系統(tǒng)在不修改原來(lái)代碼的情況下引進(jìn)新的產(chǎn)品,即滿足開(kāi)閉原則。

5.2 模式的特點(diǎn)

  • 靈活性增強(qiáng),對(duì)于新產(chǎn)品的創(chuàng)建,只需多寫(xiě)一個(gè)相應(yīng)的工廠類;
  • 高度解耦。

5.3 Kotlin 代碼實(shí)現(xiàn)

sealed class Country {
    object USA : Country() 
}

object Spain : Country() 
class Greece(val someProperty: String) : Country()
data class Canada(val someProperty: String) : Country() 

class Currency(
    val code: String
)

object CurrencyFactory {
    fun currencyForCountry(country: Country): Currency = when (country) {
         is Greece -> Currency("EUR")
         is Spain -> Currency("EUR")
         is Country.USA -> Currency("USD")
         is Canada -> Currency("CAD")
    }
}

fun main() {
    val greeceCurrency = CurrencyFactory.currencyForCountry(Greece("")).code
    println("Greece currency: $greeceCurrency")
    
    val usaCurrency = CurrencyFactory.currencyForCountry(Country.USA).code
    println("USA currency: $usaCurrency")
    
    assertThat(greeceCurrency).isEqualTo("EUR")
    assertThat(usaCurrency).isEqualTo("USD")
}

6. Kotlin 實(shí)現(xiàn)抽象工廠模式

6.1 模式的介紹

該模式定義了一種為訪問(wèn)類提供一個(gè)創(chuàng)建一組相關(guān)或相互依賴對(duì)象的接口,且訪問(wèn)類無(wú)須指定所要產(chǎn)品的具體類就能得到同族的不同等級(jí)的產(chǎn)品的模式結(jié)構(gòu),它是工廠方法模式的升級(jí)版本,工廠方法模式只生產(chǎn)一個(gè)等級(jí)的產(chǎn)品,而抽象工廠模式可生產(chǎn)多個(gè)等級(jí)的產(chǎn)品。

6.2 模式的特點(diǎn)

  • 可以在類的內(nèi)部對(duì)產(chǎn)品族中相關(guān)聯(lián)的多等級(jí)產(chǎn)品共同管理,而不必專門(mén)引入多個(gè)新的類來(lái)進(jìn)行管理;
  • 抽象工廠增強(qiáng)了程序的可擴(kuò)展性,當(dāng)增加一個(gè)新的產(chǎn)品族時(shí),不需要修改原代碼,滿足開(kāi)閉原則;
  • 當(dāng)需要產(chǎn)品族時(shí),抽象工廠可以保證客戶端始終只使用同一個(gè)產(chǎn)品的產(chǎn)品組;
  • 當(dāng)產(chǎn)品族中需要增加一個(gè)新的產(chǎn)品時(shí),所有的工廠類都需要進(jìn)行修改。

6.3 Kotlin 代碼實(shí)現(xiàn)

interface Plant

class OrangePlant : Plant

class ApplePlant : Plant

abstract class PlantFactory {
    abstract fun makePlant(): Plant

    companion object {
        inline fun <reified T : Plant> createFactory(): PlantFactory = when (T::class) {
            OrangePlant::class -> OrangeFactory()
            ApplePlant::class  -> AppleFactory()
            else               -> throw IllegalArgumentException()
        }
    }
}

class AppleFactory : PlantFactory() {
    override fun makePlant(): Plant = ApplePlant()
}

class OrangeFactory : PlantFactory() {
    override fun makePlant(): Plant = OrangePlant()
}

fun main() {
    val plantFactory = PlantFactory.createFactory<OrangePlant>()
    val plant = plantFactory.makePlant()
    println("plant is: $plant")
}

7. Kotlin 實(shí)現(xiàn)裝飾器模式

7.1 模式的介紹

該模式定義了在不改變現(xiàn)有對(duì)象結(jié)構(gòu)的情況下,動(dòng)態(tài)地給該對(duì)象增加一些職責(zé)(即增加其額外功能)的模式,它屬于對(duì)象結(jié)構(gòu)型模式。

7.2 模式的特點(diǎn)

  • 裝飾器是繼承的有力補(bǔ)充,比繼承靈活,在不改變?cè)袑?duì)象的情況下,動(dòng)態(tài)的給一個(gè)對(duì)象擴(kuò)展功能,即插即用;
  • 通過(guò)使用不用裝飾類及這些裝飾類的排列組合,可以實(shí)現(xiàn)不同效果;
  • 裝飾器模式完全遵守開(kāi)閉原則;
  • 裝飾模式會(huì)增加許多子類,過(guò)度使用會(huì)增加程序得復(fù)雜性。

7.3 Kotlin 代碼實(shí)現(xiàn)

interface CoffeeMachine {
    fun makeSmallCoffee()
    fun makeLargeCoffee()
}

class NormalCoffeeMachine : CoffeeMachine {
    override fun makeSmallCoffee() = println("makeSmallCoffee")

    override fun makeLargeCoffee() = println("makeLargeCoffee")
}

class EnhancedCoffeeMachine(val coffeeMachine: CoffeeMachine) : CoffeeMachine by coffeeMachine {

    override fun makeLargeCoffee() {
        println("makeLargeCoffee")
        coffeeMachine.makeLargeCoffee()
    }

    fun makeCoffeeWithMilk() {
        println("makeCoffeeWithMilk")
        coffeeMachine.makeSmallCoffee()
        println("add something")
    }
}

fun main() {
    val normalMachine = NormalCoffeeMachine()
    val enhancedMachine = EnhancedCoffeeMachine(normalMachine)

    // 非重寫(xiě)行為
    enhancedMachine.makeSmallCoffee()
    // 重寫(xiě)行為
    enhancedMachine.makeLargeCoffee()
    // 繼承行為
    enhancedMachine.makeCoffeeWithMilk()
}

8. Kotlin 實(shí)現(xiàn)適配器模式

8.1 模式的介紹

該模式定義了將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作。適配器模式分為類結(jié)構(gòu)型模式和對(duì)象結(jié)構(gòu)型模式兩種,前者類之間的耦合度比后者高。

8.2 模式的特點(diǎn)

  • 客戶端通過(guò)適配器可以透明地調(diào)用目標(biāo)接口;
  • 復(fù)用了現(xiàn)存的類,開(kāi)發(fā)者不需要修改原有代碼而重用現(xiàn)有的適配者類;
  • 將目標(biāo)類和適配者類解耦,解決了目標(biāo)類和適配者類接口不一致的問(wèn)題。

8.3 Kotlin 代碼實(shí)現(xiàn)

interface Temperature {
    var temperature: Double
}

class CTemperature(override var temperature: Double) : Temperature

class FTemperature(var cTemperature: CTemperature) : Temperature {

    override var temperature: Double
        get() = convertCelsiusToFahrenheit(cTemperature.temperature)
        set(temperatureInF) {
            cTemperature.temperature = convertFahrenheitToCelsius(temperatureInF)
        }

    private fun convertFToCelsius(f: Double): Double = (f - 32) * 5 / 9

    private fun convertCToFahrenheit(c: Double): Double = (c * 9 / 5) + 32
}

fun main() {
   val cTemperature = CTemperature(0.0)
   val fTemperature = FTemperature(celsiusTemperature)
   
   cTemperature.temperature = 36.6
   println("${cTemperature.temperature} C -> ${fTemperature.temperature} F")
   
   fTemperature.temperature = 100.0
   println("${fTemperature.temperature} F -> ${cTemperature.temperature} C")
}

9. 總結(jié)

到這里,有關(guān) Kotlin 在常用的設(shè)計(jì)模式中應(yīng)用都一一介紹完畢了,相信大家對(duì) Kotlin 理解和運(yùn)用有了更深的掌握。后面 Kotlin 應(yīng)用篇就比較偏泛化,比如說(shuō) Kotlin 用于 Android 開(kāi)發(fā)、iOS 開(kāi)發(fā)、Gradle 腳本開(kāi)發(fā)、服務(wù)端程序開(kāi)發(fā)、Web 開(kāi)發(fā)等。