設(shè)計模式-行為型設(shè)計模式

//本文參考菜鳥教程
設(shè)計模式主要分為三大類創(chuàng)建型模式盗迟,結(jié)構(gòu)型模式,行為型模式婆殿,本文主要講行為型模式
行為型模式诈乒,共十一種:策略模式罩扇、模板方法模式婆芦、觀察者模式怕磨、迭代子模式、責(zé)任鏈模式消约、命令模式肠鲫、備忘錄模式、狀態(tài)模式或粮、訪問者模式导饲、中介者模式、解釋器模式氯材。

1.策略模式

定義:一個類的行為或其算法可以在運行時更改渣锦。這種類型的設(shè)計模式屬于行為型模式。

interface Strategy{
    fun operation(num:Int,num2:Int):Int
}

class AddStrategyImpl:Strategy{
    override fun operation(num: Int, num2: Int) = num + num2
}

class RemoveStrategyImpl:Strategy{
    override fun operation(num: Int, num2: Int) = num - num2
}

class StrategyImpl(private var strategy: Strategy){
    fun doStrategy(num: Int,num2: Int){
        strategy.operation(num,num2)
    }
}

2.模版模式
定義:一個抽象類公開定義了執(zhí)行它的方法的方式/模板氢哮。它的子類可以按需要重寫方法實現(xiàn)

abstract class Temple {
    abstract fun one()

    abstract fun two()

    abstract fun three()

    fun dayDo() {
        one()
        two()
        three()
    }
}

class TempleTest : Temple() {
    override fun one() {
        println("1")
    }

    override fun two() {
        println("2")
    }

    override fun three() {
        println("3")
    }
}

3.觀察者模式
定義:定義對象間的一種一對多的依賴關(guān)系袋毙,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新冗尤。

interface Subject{
   fun registerObserver(o:Observer)
   fun removeObserver(o:Observer)
   fun notifyObserver()
}

interface Observer{
    fun update(message:String)
}

class WechatServer:Subject{

    var list = mutableListOf<Observer>()

    var message:String = ""

    override fun registerObserver(o: Observer) {
        list.add(o)
    }

    override fun removeObserver(o: Observer) {
        if(list.isNotEmpty()){
            list.remove(o)
        }
    }

    override fun notifyObserver() {
         list.forEach {
             it.update(message)
         }
    }

    fun setInfo(){
        println("觀測者")
        message = "粗發(fā)事件"
        notifyObserver()
    }

}
 class ObserverUser(val name:String):Observer{
     private var message: String = ""

     override fun update(message: String) {
         this.message = message
         readMessage()
     }

     fun readMessage(){
         println("獲取到消息")
     }
 }

fun main() {
    val server = WechatServer()
    val userLi = ObserverUser("li")
    server.registerObserver(userLi)
    server.setInfo()
}

4.迭代器模式
定義:提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內(nèi)部表示
參考java的iterator
5.責(zé)任鏈模式
定義:如果有多個對象有機會處理請求听盖,責(zé)任鏈可使請求的發(fā)送者和接受者解耦,請求沿著責(zé)任鏈傳遞裂七,直到有一個對象處理了它為止皆看。

abstract class AbstractLogger {
    companion object {
        val INFO = 1
        val DEBUG = 2
        val ERROR = 3
    }

    private var level: Int = 0

    var nextLogger: AbstractLogger? = null

    fun logMessage(level: Int, message: String) {
        if (this.level <= level) {
            write(message)
        }
        nextLogger?.logMessage(level, message)
    }

    protected abstract fun write(message: String)
}

class ConsoleLogger(level: Int) : AbstractLogger() {
    override fun write(message: String) {
        println("stand console::logger$message")
    }
}

class ErrorLogger(level: Int) : AbstractLogger() {
    override fun write(message: String) {
        println("error console::logger$message")
    }
}

class FileLogger(level: Int) : AbstractLogger() {
    override fun write(message: String) {
        println("File console::logger$message")
    }
}

object ChainTest {
    fun getChainOfLoggers(): AbstractLogger {
        val errorLogger: AbstractLogger = ErrorLogger(AbstractLogger.ERROR)
        val fileLogger: AbstractLogger = FileLogger(AbstractLogger.DEBUG)
        val consoleLogger: AbstractLogger = ConsoleLogger(AbstractLogger.INFO)
        errorLogger.nextLogger = fileLogger
        fileLogger.nextLogger = consoleLogger
        return errorLogger
    }
}

fun main() {
    val loggerChain: AbstractLogger = getChainOfLoggers()
    loggerChain.logMessage(AbstractLogger.INFO, "This is an information.")

    loggerChain.logMessage(
        AbstractLogger.DEBUG,
        "This is a debug level information."
    )

    loggerChain.logMessage(
        AbstractLogger.ERROR,
        "This is an error information."
    )
}

6.命令模式
定義:將一個請求封裝為一個對象,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開背零。這樣兩者之間通過命令對象進行溝通腰吟,這樣方便將命令對象進行儲存、傳遞、調(diào)用派殷、增加與管理莫其。

interface Order{
    fun execute()
}

class Stock{
    val name = "ABC"

    val quantity = 10

    fun buy(){
        println("bubbly")
    }

    fun sell(){
        println("sell")
    }
}

class SellStock(private val stock: Stock):Order{
    override fun execute() {
        stock.sell()
    }
}

class BuyStock(private val stock: Stock):Order{
    override fun execute() {
        stock.buy()
    }
}

class Broker {
    private val orderList: MutableList<Order> = ArrayList()
    fun takeOrder(order: Order) {
        orderList.add(order)
    }

    fun placeOrders() {
        for (order in orderList) {
            order.execute()
        }
        orderList.clear()
    }
}

fun main() {
    val abcStock = Stock()
    val buyStockOrder = BuyStock(abcStock)
    val sellStockOrder = SellStock(abcStock)
    val broker = Broker()
    broker.takeOrder(buyStockOrder)
    broker.takeOrder(sellStockOrder)
    broker.placeOrders()
}

7.狀態(tài)模式
定義:在狀態(tài)模式中,我們創(chuàng)建表示各種狀態(tài)的對象和一個行為隨著狀態(tài)對象改變而改變的 context 對象禾乘。

data class StateContext(var state: State? = null)

interface State{
    fun doAction(context: StateContext)
}

class StartState:State{
    override fun doAction(context: StateContext) {
        println("is start state")

       context.state = this
    }

    override fun toString(): String {
        return "Start state"
    }
}

class StopState:State{
    override fun doAction(context: StateContext) {
        println("is stop state")
        context.state = this
    }

    override fun toString(): String {
        return "stop state"
    }
}

fun main() {
    val context = StateContext()
    val startState = StartState()
    startState.doAction(context)
    println(context.state.toString())
    val stopState = StopState()
    stopState.doAction(context)
    println(context.state.toString())
}

8.備忘錄模式
定義: 在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài)虽缕,并在該對象之外保存這個狀態(tài)始藕,以便以后當(dāng)需要時能將該對象恢復(fù)到原先保存的狀態(tài)。該模式又叫快照模式


data class MementoTest(var state:String)

class Originator{
    var state:String = ""

    fun saveStateToMemento():MementoTest = MementoTest(state)

    fun getStateFromMemento(mementoTest: MementoTest){
        state = mementoTest.state
    }
}

class CareTaker {
    private val mementoList: MutableList<MementoTest> = ArrayList<MementoTest>()
    fun add(state: MementoTest) {
        mementoList.add(state)
    }

    operator fun get(index: Int): MementoTest {
        return mementoList[index]
    }
}

fun main() {
    val originator = Originator()
    val careTaker = CareTaker()
    originator.state = "State #1"
    originator.state = "State #2"
    careTaker.add(originator.saveStateToMemento())
    originator.state = "State #3"
    careTaker.add(originator.saveStateToMemento())
    originator.state = "State #4"
    println("Current State: " + originator.state)
    originator.getStateFromMemento(careTaker[0])
    println("First saved State: " + originator.state)
    originator.getStateFromMemento(careTaker[1])
    println("Second saved State: " + originator.state)
}

9.訪問者模式
定義:我們使用了一個訪問者類氮趋,它改變了元素類的執(zhí)行算法伍派。通過這種方式,元素的執(zhí)行算法可以隨著訪問者改變而改變剩胁。這種類型的設(shè)計模式屬于行為型模式诉植。根據(jù)模式,元素對象已接受訪問者對象昵观,這樣訪問者對象就可以處理元素對象上的操作晾腔。

class VisitorTest {
    interface ComputerPart{
        fun accept(computerPartVisitor: ComputerPartVisitor)
    }

    interface ComputerPartVisitor {
        fun visit(computer: Computer?)
        fun visit(mouse: Mouse?)
        fun visit(keyboard: Keyboard?)
        fun visit(monitor: Monitor?)
    }


    class Keyboard:ComputerPart{
        override fun accept(computerPartVisitor: ComputerPartVisitor) {
            computerPartVisitor.visit(this)
        }
    }

    class Mouse:ComputerPart{
        override fun accept(computerPartVisitor: ComputerPartVisitor) {
            computerPartVisitor.visit(this)
        }
    }

    class Monitor:ComputerPart{
        override fun accept(computerPartVisitor: ComputerPartVisitor) {
            computerPartVisitor.visit(this)
        }
    }

    class Computer : ComputerPart {
        private var parts: Array<ComputerPart> = arrayOf(Mouse(), Keyboard(), Monitor())
        override fun accept(computerPartVisitor: ComputerPartVisitor) {
            for (i in parts.indices) {
                parts[i].accept(computerPartVisitor)
            }
            computerPartVisitor.visit(this)
        }
    }

    class ComputerPartDisplayVisitor : ComputerPartVisitor {
        override fun visit(computer: Computer?) {
            println("Displaying Computer.")
        }

        override fun visit(mouse: Mouse?) {
            println("Displaying Mouse.")
        }

        override fun visit(keyboard: Keyboard?) {
            println("Displaying Keyboard.")
        }

        override fun visit(monitor: Monitor?) {
            println("Displaying Monitor.")
        }
    }
}

fun main() {
    val computer: ComputerPart = VisitorTest.Computer()
    computer.accept(ComputerPartDisplayVisitor())
}

10.中介者模式
定義:是用來降低多個對象和類之間的通信復(fù)雜性舌稀。這種模式提供了一個中介類,該類通常處理不同類之間的通信灼擂,并支持松耦合壁查,使代碼易于維護。

class MediatorTest {
    object ChatRoom {
        fun showMessage(user: User, message: String) {
            println(
                Date().toString()
                    .toString() + " [" + user.name + "] : " + message
            )
        }
    }

    class User(var name: String) {
        fun sendMessage(message: String) {
                ChatRoom.showMessage(this, message)
        }
    }
}

fun main() {
    val robert = User("Robert")
    val john = User("John")
    robert.sendMessage("Hi! John!")
    john.sendMessage("Hello! Robert!")
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剔应,一起剝皮案震驚了整個濱河市睡腿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峻贮,老刑警劉巖席怪,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纤控,居然都是意外死亡何恶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門嚼黔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來细层,“玉大人,你說我怎么就攤上這事唬涧∫呤辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵碎节,是天一觀的道長捧搞。 經(jīng)常有香客問我,道長狮荔,這世上最難降的妖魔是什么胎撇? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮殖氏,結(jié)果婚禮上晚树,老公的妹妹穿的比我還像新娘。我一直安慰自己雅采,他們只是感情好爵憎,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著婚瓜,像睡著了一般宝鼓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巴刻,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天愚铡,我揣著相機與錄音,去河邊找鬼胡陪。 笑死沥寥,一個胖子當(dāng)著我的面吹牛正蛙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播营曼,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愚隧!你這毒婦竟也來了蒂阱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤狂塘,失蹤者是張志新(化名)和其女友劉穎录煤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荞胡,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡妈踊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泪漂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片廊营。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖萝勤,靈堂內(nèi)的尸體忽然破棺而出露筒,到底是詐尸還是另有隱情,我是刑警寧澤敌卓,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布慎式,位于F島的核電站,受9級特大地震影響趟径,放射性物質(zhì)發(fā)生泄漏瘪吏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一蜗巧、第九天 我趴在偏房一處隱蔽的房頂上張望掌眠。 院中可真熱鬧,春花似錦幕屹、人聲如沸扇救。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迅腔。三九已至,卻和暖如春靠娱,著一層夾襖步出監(jiān)牢的瞬間沧烈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工像云, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锌雀,地道東北人蚂夕。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像腋逆,于是被迫代替她去往敵國和親婿牍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容