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

狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換

這篇具有很好參考價值的文章主要介紹了狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

?某信用卡業(yè)務(wù)系統(tǒng),銀行賬戶存在3種狀態(tài),且在不同狀態(tài)下存在不同的行為:

1)正常狀態(tài)(余額大等于0),用戶可以存款也可以取款;

2)透支狀態(tài)(余額小于0且大于-2000),用戶可以存款也可以取款,但需要對欠款支付利息。

3)受限狀態(tài)(余額小等于-2000),用戶只能存款,還需要對欠款支付利息。

狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換,# 設(shè)計(jì)模式的藝術(shù),狀態(tài)模式,設(shè)計(jì)模式

圖 偽代碼實(shí)現(xiàn)上述需求

上面代碼存在以下問題:

1)獲取狀態(tài)時,有好多個if分支,如果再增加幾個狀態(tài),則需要增加判斷條件,同時也不符合開閉原則。

2)在進(jìn)行存取款操作時,有對狀態(tài)進(jìn)行判斷的條件,行為受到狀態(tài)的限制。

為了更好對具有多種狀態(tài)的對象進(jìn)行設(shè)計(jì),可以使用一種被稱作狀態(tài)模式的設(shè)計(jì)模式。

1 狀態(tài)模式

狀態(tài)模式(State Pattern)允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的狀態(tài)類。是一種對象行為型模式。

狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換,# 設(shè)計(jì)模式的藝術(shù),狀態(tài)模式,設(shè)計(jì)模式

圖 狀態(tài)模式UML

Context:環(huán)境類,是擁有多種狀態(tài)的對象。由于環(huán)境類的狀態(tài)存在多樣性且在不同狀態(tài)下對象的行為有所不同,因此將狀態(tài)獨(dú)立出去形成單獨(dú)的狀態(tài)類。

State:抽象狀態(tài)類,用于定義一個接口以封裝與環(huán)境類的一個特定狀態(tài)相關(guān)的行為。在抽象狀態(tài)類中聲明各種不同狀態(tài)對應(yīng)的方法,而在其子類中實(shí)現(xiàn)這些方法。

ConcreteState:具體狀態(tài)類,是抽象狀態(tài)類的子類,每個子類實(shí)現(xiàn)與環(huán)境類的一個狀態(tài)相關(guān)的行為。

public class UserAccount {

    private double balance;

    private CardState cardState;

    public UserAccount(double balance) {
        this.balance = balance;
        cardState = new NormalCardState(this);
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public void deposit(double money) {
        System.out.println("存錢 " + money);
        cardState.deposit(money);
        changeState();
        System.out.println("信用卡余額:"+ balance + ",狀態(tài)是:" + cardState.getState());
        System.out.println("------------------------------");
    }

    public void withdraw(double money) {
        if (balance - money < 0) {
            System.out.println("借錢 " + money + ",利息利率是0.01");
        } else {
            System.out.println("取款 " + money);
        }
        cardState.withdraw(money);
        changeState();
        System.out.println("信用卡余額:"+ balance + ",狀態(tài)是:" + cardState.getState());
        System.out.println("------------------------------");
    }

    public void changeState() {
        if (balance > 0) {
            if (!"正常".equals(cardState.getState())) cardState = new NormalCardState(this);
        } else if (balance > -2000) {
            if (!"透支".equals(cardState.getState())) cardState = new OverdraftCardState(this);
        } else {
            if (!"受限".equals(cardState.getState())) cardState = new LimitationCardState(this);
        }
    }

    public void setCardState(CardState cardState) {
        this.cardState = cardState;
    }
}

public abstract class CardState {

    protected final UserAccount userAccount;

    public CardState(UserAccount userAccount) {
        this.userAccount = userAccount;
    }

    public abstract void deposit(double money); // 存款

    public abstract void withdraw(double money); // 取款

    public abstract void payInterest(); // 支付利息

    public abstract String getState(); // 獲取狀態(tài)

}

public class BankService {

    public static void main(String[] args) {
        // 開戶
        UserAccount userAccount = new UserAccount(1000);
        userAccount.withdraw(500);
        userAccount.deposit(200);
        userAccount.withdraw(1000);
        userAccount.deposit(100);
        userAccount.withdraw(2000);
        userAccount.withdraw(500);
    }

}

//取款 500.0
//信用卡余額:500.0,狀態(tài)是:正常
//------------------------------
//存錢 200.0
//信用卡余額:700.0,狀態(tài)是:正常
//------------------------------
//借錢 1000.0,利息利率是0.01
//信用卡余額:-300.0,狀態(tài)是:透支
//------------------------------
//存錢 100.0
//支付利息:-3.0
//信用卡余額:-203.0,狀態(tài)是:透支
//------------------------------
//借錢 2000.0,利息利率是0.01
//支付利息:-2.0300000000000002
//信用卡余額:-2205.03,狀態(tài)是:受限
//------------------------------
//借錢 500.0,利息利率是0.01
//該賬戶已受限,不能取款
//信用卡余額:-2205.03,狀態(tài)是:受限
//------------------------------


public class NormalCardState extends CardState{

    public NormalCardState(UserAccount userAccount) {
        super(userAccount);
    }

    @Override
    public void deposit(double money) {
        userAccount.setBalance(userAccount.getBalance() + money);
    }

    @Override
    public void withdraw(double money) {
        userAccount.setBalance(userAccount.getBalance() - money);
    }

    @Override
    public void payInterest() {

    }

    @Override
    public String getState() {
        return "正常";
    }

}

public class OverdraftCardState extends CardState{

    public OverdraftCardState(UserAccount userAccount) {
        super(userAccount);
    }

    @Override
    public void deposit(double money) {
        payInterest();
        userAccount.setBalance(userAccount.getBalance() + money);
    }

    @Override
    public void withdraw(double money) {
        payInterest();
        userAccount.setBalance(userAccount.getBalance() - money);
    }

    @Override
    public void payInterest() {
        System.out.println("支付利息:" + userAccount.getBalance() * 0.01);
        userAccount.setBalance(userAccount.getBalance() * ( 1 + 0.01));
    }

    @Override
    public String getState() {
        return "透支";
    }
}

public class LimitationCardState extends CardState{

    public LimitationCardState(UserAccount userAccount) {
        super(userAccount);
    }

    @Override
    public void deposit(double money) {
        payInterest();
        userAccount.setBalance(userAccount.getBalance() + money);
    }

    @Override
    public void withdraw(double money) {
        System.out.println("該賬戶已受限,不能取款");
    }

    @Override
    public void payInterest() {
        System.out.println("支付利息:" + userAccount.getBalance() * 0.01);
        userAccount.setBalance(userAccount.getBalance() * ( 1 + 0.01));
    }

    @Override
    public String getState() {
        return "受限";
    }
}

使用狀態(tài)模式后,在編碼過程中,可以不要在關(guān)系具體狀態(tài),只需專注實(shí)現(xiàn)具體狀態(tài)下的業(yè)務(wù)。

1.1 狀態(tài)轉(zhuǎn)換方式

在狀態(tài)模式中,環(huán)境類的狀態(tài)轉(zhuǎn)換方式有兩種:

1)在環(huán)境類完成轉(zhuǎn)換。(上面代碼是以這種形式)

2)在具體狀態(tài)類中完成轉(zhuǎn)換。

狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換,# 設(shè)計(jì)模式的藝術(shù),狀態(tài)模式,設(shè)計(jì)模式

圖 兩種狀態(tài)轉(zhuǎn)換方式的比較

如果新增狀態(tài)類,則兩種方式都需要在各自的類中做修改。都不符合開閉原則。

1.2 共享狀態(tài)

在有些情況下,多個環(huán)境類對象需要共享一個狀態(tài),這時需要把狀態(tài)對象定義為一個靜態(tài)成員對象。

需求:一個房間有兩個開關(guān)來控制燈泡的開關(guān)。開關(guān)等功能是固定的(打開只能使燈泡亮起,關(guān)閉只能使燈泡熄滅。

public class LightSwitch {

    private final static LightState onState = new OnLightState(),offState = new OffLightState();

    private static LightState lightState = offState;

    private final String name;

    public LightSwitch(String name) {
        this.name = name;
    }

    public static void changeLightState(String type) {
        if ("on".equalsIgnoreCase(type)) {
            lightState = onState;
        } else {
            lightState = offState;
        }
    }

    public void off() {
        System.out.println(name + "關(guān)閉操作");
        lightState.off(this);
    }

    public void on() {
        System.out.println(name + "打開操作");
        lightState.on(this);
    }

}

public abstract class LightState {

    public abstract void on(LightSwitch lightSwitch);

    public abstract void off(LightSwitch lightSwitch);
}

public class OnLightState extends LightState{

    @Override
    public void on(LightSwitch lightSwitch) {
        System.out.println("燈泡已打開");
        System.out.println("--------------");
    }

    @Override
    public void off(LightSwitch lightSwitch) {
        System.out.println("關(guān)閉成功");
        LightSwitch.changeLightState("off");
        System.out.println("--------------");
    }

}

public class OffLightState extends LightState{

    @Override
    public void on(LightSwitch lightSwitch) {
        System.out.println("打開成功");
        LightSwitch.changeLightState("on");
        System.out.println("--------------");
    }

    @Override
    public void off(LightSwitch lightSwitch) {
        System.out.println("燈泡已關(guān)閉");
        System.out.println("--------------");
    }

}

public class PeopleOpera {
    public static void main(String[] args) {
        LightSwitch lightSwitch1 = new LightSwitch("開關(guān)1");
        LightSwitch lightSwitch2 = new LightSwitch("開關(guān)2");

        lightSwitch1.on();
        lightSwitch2.off();
        lightSwitch1.off();
        lightSwitch1.on();
        lightSwitch2.on();
        lightSwitch2.off();
    }
}

//開關(guān)1打開操作
//打開成功
//--------------
//開關(guān)2關(guān)閉操作
//關(guān)閉成功
//--------------
//開關(guān)1關(guān)閉操作
//燈泡已關(guān)閉
//--------------
//開關(guān)1打開操作
//打開成功
//--------------
//開關(guān)2打開操作
//燈泡已打開
//--------------
//開關(guān)2關(guān)閉操作
//關(guān)閉成功
//--------------

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

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

1)環(huán)境類轉(zhuǎn)換狀態(tài)方式,封裝狀態(tài)的轉(zhuǎn)換規(guī)則,對狀態(tài)轉(zhuǎn)換代碼集中管理。

2)將所有與具體狀態(tài)有關(guān)的行為都封裝在一個類中。

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

4)在具體狀態(tài)類中轉(zhuǎn)換狀態(tài)方式,將狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對象合成一起,避免使用龐大的條件語句塊來將業(yè)務(wù)方法和狀態(tài)轉(zhuǎn)換代碼交織在一起。

缺點(diǎn):

1)增加了類和對象的個數(shù)。

2)實(shí)現(xiàn)較為復(fù)雜,增加了系統(tǒng)設(shè)計(jì)難度。

3)對開閉原則的支持并不好。

3 適用場景

1)對象的行為依賴它的狀態(tài),且狀態(tài)之間互相轉(zhuǎn)換。

2)代碼中包含大量與對象狀態(tài)有關(guān)的條件語句。文章來源地址http://www.zghlxwxcb.cn/news/detail-715948.html

到了這里,關(guān)于狀態(tài)模式-對象狀態(tài)及其轉(zhuǎn)換的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

    ? ? ? ? 組合模式組合多個對象形成樹形結(jié)構(gòu)以表示具有“部分-整體”關(guān)系的層次結(jié)構(gòu)。組合模式對單個對象(即葉子對象)和組合對象(即容器對象)的使用具有一致性,又可以稱為“部分—整體”(Part-Whole)模式,它是一種對象結(jié)構(gòu)型模式。 myclass.h myclass.cpp main.cpp ?

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

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

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

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

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

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

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

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

    2024年01月18日
    瀏覽(23)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 策略模式

    ? ? ? ? 策略模式定義一系列算法類,將每一個算法封裝起來,并讓它們可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而變化,也稱為政策模式。策略模式是一種對象行為模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 1.?策略模式提供了對開閉原則的完美支持。用戶可以在不

    2024年01月25日
    瀏覽(23)
  • 《設(shè)計(jì)模式的藝術(shù)》筆記 - 原型模式

    ? ? ? ? 使用原型實(shí)例指定創(chuàng)建對象的種類,并且通過克隆這些原型創(chuàng)建新的對象。原型模式是一種對象創(chuàng)建型模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 優(yōu)點(diǎn): ? ? ? ? 1.?當(dāng)創(chuàng)建新的對象實(shí)例較為復(fù)雜時,使用原型模式可以簡化對象的創(chuàng)建過程,通過復(fù)制一個已有實(shí)例可以提

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

    ? ? ? ? 迭代器模式提供一種方法來訪問聚合對象,而不用暴露這個對象的內(nèi)部表示,其別名為游標(biāo)(Cursor)。迭代器模式是一種對象行為型模式。 myclass.h myclass.cpp main.cpp ? ? ? ? 1. 支持以不同的方式遍歷一個聚合對象,在同一個聚合對象上可以定義多種遍歷方式。在迭代

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

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

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

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

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

    2024年02月02日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包