国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《設(shè)計(jì)模式的藝術(shù)》筆記 - 狀態(tài)模式

這篇具有很好參考價(jià)值的文章主要介紹了《設(shè)計(jì)模式的藝術(shù)》筆記 - 狀態(tài)模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

介紹

? ? ? ? 狀態(tài)模式允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)似乎修改了它的類。其別名為狀態(tài)對(duì)象,狀態(tài)模式是一種對(duì)象行為模式。

實(shí)現(xiàn)

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>
#include <unordered_map>
#include <atomic>
#include <vector>
#include <memory>

class State {   // 抽象狀態(tài)類
public:
    virtual void handle() = 0;
};

class Context { // 環(huán)境類
public:
    Context();
    void setState(const std::shared_ptr<State> &state);
    void request(int num);
    void changeState();

private:
    std::shared_ptr<State> m_state;
    int m_value;
};

class ConcreteStateA : public State {    // 具體狀態(tài)類A
public:
    void handle() override;
};

class ConcreteStateB : public State {    // 具體狀態(tài)類B
public:
    void handle() override;
};


#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"
#include <thread>
#include <unistd.h>
#include <sstream>

Context::Context() {
    m_value = 0;
    m_state.reset(new ConcreteStateA());
}

void Context::setState(const std::shared_ptr<State> &state) {
    m_state = state;
}

void Context::request(int num) {
    int tmp = m_value;
    m_value += num;
    if ((tmp >= 0 && m_value < 0) || (tmp < 0 && m_value >= 0)) {
        changeState();
    }
    m_state->handle();
}

void Context::changeState() {
    std::cout << "切換狀態(tài)" << std::endl;
    if (m_value >= 0) {
        m_state.reset(new ConcreteStateA());
    } else {
        m_state.reset(new ConcreteStateB());
    }
}

void ConcreteStateA::handle() {
    std::cout << "ConcreteStateA::handle()" << std::endl;
}

void ConcreteStateB::handle() {
    std::cout << "ConcreteStateB::handle()" << std::endl;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Context *context = new Context;
    context->request(0);
    std::cout << "-------------------" << std::endl;
    context->request(-10);
    std::cout << "-------------------" << std::endl;
    context->request(20);

    return 0;
}

總結(jié)

優(yōu)點(diǎn)

? ? ? ? 1.?封裝了狀態(tài)的轉(zhuǎn)換規(guī)則。在狀態(tài)模式中可以將狀態(tài)的轉(zhuǎn)換代碼封裝在環(huán)境類或者具體狀態(tài)類中,對(duì)狀態(tài)轉(zhuǎn)換代碼進(jìn)行集中管理,而不是分散在一個(gè)個(gè)業(yè)務(wù)方法中。

? ? ? ? 2.?將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類中,只需要注入一個(gè)不同的狀態(tài)對(duì)象即可使環(huán)境對(duì)象擁有不同的行為。

? ? ? ? 3.?允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體,而不是提供一個(gè)巨大的條件語(yǔ)句塊。狀態(tài)模式可以避免使用龐大的條件語(yǔ)句來(lái)將業(yè)務(wù)方法和狀態(tài)轉(zhuǎn)換代碼交織在一起。

? ? ? ? 4.?可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)。

缺點(diǎn)

? ? ? ? 1.?狀態(tài)模式的使用必然會(huì)增加系統(tǒng)中類和對(duì)象的個(gè)數(shù),導(dǎo)致系統(tǒng)運(yùn)行開(kāi)銷增大。

? ? ? ? 2.?狀態(tài)模式的程序結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂,增加系統(tǒng)設(shè)計(jì)的難度。

? ? ? ? 3.?狀態(tài)模式對(duì)開(kāi)閉原則的支持并不太好。增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無(wú)法轉(zhuǎn)換到新增狀態(tài);而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼。

適用場(chǎng)景

? ? ? ? 1.?對(duì)象的行為依賴于它的狀態(tài)(例如某些屬性值),狀態(tài)的改變將導(dǎo)致行為的變化。

? ? ? ? 2.?在代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語(yǔ)句。這些條件語(yǔ)句的出現(xiàn),會(huì)導(dǎo)致代碼的可維護(hù)性和靈活性變差,不能方便地增加和刪除狀態(tài),并且導(dǎo)致客戶類與類庫(kù)之間的耦合增強(qiáng)。

練習(xí)

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>
#include <unordered_map>
#include <atomic>
#include <vector>
#include <memory>

class Level {   // 抽象狀態(tài)類
public:
    virtual void play() = 0;
    virtual void doubleScore();
    virtual void changeCards();
    virtual void peekCards();
};

class CardsGame {
public:
    CardsGame();
    ~CardsGame();

    void play(int score);   // 模擬玩游戲得分
    void doubleScore();
    void changeCards();
    void peekCards();

private:
    Level *m_level;     // 當(dāng)前等級(jí)
    Level *m_primary;   // 入門級(jí)
    Level *m_secondary; // 熟練級(jí)
    Level *m_professional;  // 高手級(jí)
    Level *m_final;     // 骨灰級(jí)
    int m_score;    // 得分
};

class PrimaryLevel : public Level {
public:
    void play() override;

    void doubleScore() override;

    void changeCards() override;

    void peekCards() override;
};

class SecondaryLevel : public Level {
public:
    void play() override;

    void changeCards() override;

    void peekCards() override;
};

class ProfessionalLevel : public Level {
public:
    void play() override;

    void peekCards() override;
};

class FinalLevel : public Level {
public:
    void play() override;
};


#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"
#include <thread>
#include <unistd.h>
#include <sstream>

void Level::doubleScore() {
    std::cout << "勝利積分加倍" << std::endl;
}

void Level::changeCards() {
    std::cout << "換牌" << std::endl;
}

void Level::peekCards() {
    std::cout << "偷看他人的牌" << std::endl;
}

CardsGame::CardsGame() {
    m_primary = new PrimaryLevel();
    m_secondary = new SecondaryLevel();
    m_professional = new ProfessionalLevel();
    m_final = new FinalLevel();
    m_level = m_primary;
    m_score = 0;
}

CardsGame::~CardsGame() {
    if (m_primary) {
        delete m_primary;
    }
    if (m_secondary) {
        delete m_secondary;
    }
    if (m_professional) {
        delete m_professional;
    }
    if (m_final) {
        delete m_final;
    }
}

void CardsGame::play(int score) {
    m_level->play();
    m_score += score;
    if (m_score < 100) {
        if (m_level != m_primary) {
            std::cout << "切換到入門級(jí)" << std::endl;
            m_level = m_primary;
        }
    } else if (m_score < 500) {
        if (m_level != m_secondary) {
            std::cout << "切換到熟練級(jí)" << std::endl;
            m_level = m_secondary;
        }
    } else if (m_score < 1000) {
        if (m_level != m_professional) {
            std::cout << "切換到高手級(jí)" << std::endl;
            m_level = m_professional;
        }
    } else {
        if (m_level != m_final) {
            std::cout << "切換到骨灰級(jí)" << std::endl;
            m_level = m_final;
        }
    }
}

void CardsGame::changeCards() {
    m_level->changeCards();
}

void CardsGame::doubleScore() {
    m_level->doubleScore();
}

void CardsGame::peekCards() {
    m_level->peekCards();
}

void PrimaryLevel::play() {
    std::cout << "入門級(jí)游戲開(kāi)始" << std::endl;
}

void PrimaryLevel::doubleScore() {
    std::cout << "入門級(jí)不支持游戲勝利積分加倍功能" << std::endl;
}

void PrimaryLevel::changeCards() {
    std::cout << "入門級(jí)不支持換牌功能" << std::endl;
}

void PrimaryLevel::peekCards() {
    std::cout << "入門級(jí)不支持偷看他人的牌功能" << std::endl;
}

void SecondaryLevel::play() {
    std::cout << "熟練級(jí)游戲開(kāi)始" << std::endl;
}

void SecondaryLevel::changeCards() {
    std::cout << "熟練級(jí)不支持換牌功能" << std::endl;
}

void SecondaryLevel::peekCards() {
    std::cout << "熟練級(jí)不支持偷看他人的牌功能" << std::endl;
}

void ProfessionalLevel::play() {
    std::cout << "高手級(jí)游戲開(kāi)始" << std::endl;
}

void ProfessionalLevel::peekCards() {
    std::cout << "高手級(jí)不支持偷看他人的牌功能" << std::endl;
}

void FinalLevel::play() {
    std::cout << "骨灰級(jí)游戲開(kāi)始" << std::endl;
}

main.cpp文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-824368.html

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    CardsGame *cardsGame = new CardsGame();
    cardsGame->doubleScore();
    cardsGame->changeCards();
    cardsGame->peekCards();
    cardsGame->play(200);
    std::cout << "------------------------" << std::endl;
    cardsGame->doubleScore();
    cardsGame->changeCards();
    cardsGame->peekCards();
    cardsGame->play(500);
    std::cout << "------------------------" << std::endl;
    cardsGame->doubleScore();
    cardsGame->changeCards();
    cardsGame->peekCards();
    cardsGame->play(500);
    std::cout << "------------------------" << std::endl;
    cardsGame->doubleScore();
    cardsGame->changeCards();
    cardsGame->peekCards();
    cardsGame->play(0);

    delete cardsGame;

    return 0;
}

到了這里,關(guān)于《設(shè)計(jì)模式的藝術(shù)》筆記 - 狀態(tài)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 裝飾模式

    ? ? ? ? 裝飾模式動(dòng)態(tài)地給一個(gè)對(duì)象增加一些額外的職責(zé),就增加對(duì)象功能來(lái)說(shuō),裝飾模式比生成子類實(shí)現(xiàn)更為靈活。裝飾模式是一種對(duì)象結(jié)構(gòu)型模式。 ?myclass.h myclass.cpp main.cpp ? ? ? ? 1.?對(duì)于擴(kuò)展一個(gè)對(duì)象的功能,裝飾模式比繼承更加靈活性,不會(huì)導(dǎo)致類的個(gè)數(shù)急劇增加

    2024年01月19日
    瀏覽(24)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 命令模式

    ? ? ? ? 命令模式將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,以及支持可撤銷的操作。命令模式是一種對(duì)象行為模式,其別名為動(dòng)作模式或事務(wù)模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 只需要增加一個(gè)CommandQueue類即可

    2024年01月20日
    瀏覽(29)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 代理模式

    ? ? ? ? 代理模式是給某一個(gè)對(duì)象提供一個(gè)代理,并由代理對(duì)象控制對(duì)原對(duì)象的引用。代理模式是一種對(duì)象結(jié)構(gòu)型模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 1.?代理模式能夠協(xié)調(diào)調(diào)用者和被調(diào)用者,在一定程度上降低了系統(tǒng)的耦合度,滿足迪米特法則。 ? ? ? ? 2.?客戶端可以

    2024年01月19日
    瀏覽(14)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 橋接模式

    ? ? ? ? 橋接模式將抽象部分與其實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。它是一種對(duì)象結(jié)構(gòu)型模式,又稱為柄體模式或接口模式 myclass.h myclass.cpp main.cpp ? ? ? ? 1.?分離抽象接口及其實(shí)現(xiàn)部分。橋接模式使用“對(duì)象間的關(guān)聯(lián)關(guān)系”解耦了抽象和實(shí)現(xiàn)之間固有的綁定關(guān)系,

    2024年01月18日
    瀏覽(23)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 簡(jiǎn)單工廠模式

    《設(shè)計(jì)模式的藝術(shù)》筆記 - 簡(jiǎn)單工廠模式

    ? ? ? ? 定義一個(gè)工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有相同的父類。因?yàn)樵诤?jiǎn)單工廠模式中用于創(chuàng)建實(shí)例的方法是靜態(tài)方法,因此簡(jiǎn)單工廠模式又被稱為靜態(tài)工廠方法模式,屬于類創(chuàng)建型模式 ? ? ? ? 將Factory合并到父類Product中,此時(shí)

    2024年01月16日
    瀏覽(21)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 單例模式

    ????????單例模式優(yōu)點(diǎn)是可以確保系統(tǒng)中只存在單個(gè)對(duì)象實(shí)例,缺點(diǎn)是不便擴(kuò)展,一定程度上違背單一原則,既提供業(yè)務(wù)方法,又提供創(chuàng)建對(duì)象方法 ? ? ? ? 在類加載的時(shí)候就創(chuàng)建好對(duì)象,獲取對(duì)象時(shí)直接返回即可 ? ? ? ? 在類加載的時(shí)候沒(méi)有創(chuàng)建對(duì)象,第一次獲取對(duì)象

    2024年02月02日
    瀏覽(18)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 享元模式

    ? ? ? ? 享元模式運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度對(duì)象的復(fù)用。系統(tǒng)只使用少量的對(duì)象,而這些對(duì)象都很相似,狀態(tài)變化很小,可以實(shí)現(xiàn)對(duì)象的多次復(fù)用。由于享元模式要求能夠共享的對(duì)象必須是細(xì)粒度對(duì)象,因此它又稱為輕量級(jí)模式,是一種對(duì)象結(jié)構(gòu)型模式。 myclass.

    2024年01月19日
    瀏覽(20)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 抽象工廠模式

    ? ? ? ? 提供了一個(gè)創(chuàng)建一系列相關(guān)或相互依賴的對(duì)象的接口,而無(wú)須指定它們具體的類。抽象工廠模式又稱為Kit模式,它是一種對(duì)象創(chuàng)建型模式。 ? ? ? ? 在抽象工廠模式中,每個(gè)具體工廠都提供了多個(gè)工廠方法用于產(chǎn)生多種不同類型的產(chǎn)品,這些產(chǎn)品構(gòu)成了一個(gè)產(chǎn)品族。

    2024年01月16日
    瀏覽(27)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 建造者模式

    ? ? ? ? 建造者模式將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。建造這模式是一種對(duì)象創(chuàng)建型模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 優(yōu)點(diǎn): ? ? ? ? 1.?在建造者模式中,客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié),將產(chǎn)品本身與產(chǎn)品的創(chuàng)建

    2024年01月16日
    瀏覽(24)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 工廠方法模式

    ? ? ? ? 在簡(jiǎn)單工廠模式中,當(dāng)系統(tǒng)中需要引入新的產(chǎn)品時(shí),由于靜態(tài)工廠方法通過(guò)所傳入的參數(shù)的不同來(lái)創(chuàng)建不同的產(chǎn)品,這必定要修改工廠類的源代碼,將違背開(kāi)閉原則。因此,工廠方法模式應(yīng)運(yùn)而生。工廠方法模式是定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定將哪一個(gè)

    2024年01月23日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包