真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java設(shè)計(jì)模式之狀態(tài)模式的示例分析

這篇文章給大家分享的是有關(guān)java設(shè)計(jì)模式之狀態(tài)模式的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)公司主營(yíng)杜集網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app軟件開發(fā)公司,杜集h5小程序開發(fā)搭建,杜集網(wǎng)站營(yíng)銷推廣歡迎杜集等地區(qū)企業(yè)咨詢

定義

很多時(shí)候,一個(gè)對(duì)象的行為會(huì)根據(jù)一個(gè)動(dòng)態(tài)的屬性變化而變化,這樣的一個(gè)對(duì)象我們可以稱為是有狀態(tài)的對(duì)象.

那么狀態(tài)模式就是允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)候去改變對(duì)象的行為. 狀態(tài)模式的關(guān)鍵就是區(qū)分其對(duì)象內(nèi)部動(dòng)態(tài)變化狀態(tài)是什么.

現(xiàn)實(shí)世界舉例論證

一個(gè)電燈泡,有一個(gè)開關(guān)按鈕, 默認(rèn)是關(guān)閉狀態(tài),按一下切換到亮燈狀態(tài),再按一下切換到關(guān)閉狀態(tài),循環(huán)往復(fù).

我們使用面向?qū)ο髮懛▽?shí)現(xiàn)上述的場(chǎng)景.

class Button {

    constructor (light) {

        this.light = light;

    }

    onPress () {

        if (this.light.status === 'close') {

            this.light.status = 'open';

            console.log('開燈');

        } else {

            this.light.status = 'close';

            console.log('關(guān)燈');

        }

    }

}

class Light {

    constructor () {

        this.status = 'close';

    }

}

const light = new Light();

const button = new Button(light);

button.onPress();

button.onPress();

button.onPress();

但是現(xiàn)實(shí)場(chǎng)景中有些燈的狀態(tài)不只是開關(guān),比如它還是只有一個(gè)開關(guān),第一次按是開弱光,再按是開強(qiáng)光,再按才是關(guān),依次循環(huán).

此時(shí)我們的代碼如何按照下述方法擴(kuò)展:

class Button {

    constructor (light) {

        this.light = light;

    }

    onPress () {

        if (this.light.status === 'close') {

            this.light.status = 'light';

            console.log('開弱光燈');

        } else if (this.light.status === 'light') {

            this.light.status = 'strong';

            console.log('開強(qiáng)光燈');

        } else {

            this.light.status = 'close';

            console.log('關(guān)燈');

        }

    }

}

你會(huì)發(fā)下上述代碼的缺點(diǎn):

違反SOLID中的O原則(對(duì)擴(kuò)展開發(fā),對(duì)修改關(guān)閉)。

每次增加一個(gè)燈的狀態(tài),就要修該onPress方法,使得代碼非常不穩(wěn)定,不利于維護(hù).

過(guò)多的if else, 不利于代碼閱讀.

我們可以使用狀態(tài)模式對(duì)上述代碼進(jìn)行重構(gòu).

找出狀態(tài)對(duì)象中的可變屬性,將其抽象為一個(gè)單獨(dú)的類,跟這個(gè)狀態(tài)有關(guān)的行為都封裝在其類里面.

class Button {

    constructor (light) {

        this.weakLightStatus = new WeakLightStatus(light);

        this.strongLightStatus = new StrongLightStatus(light);

        this.offLightStatus = new OffLightStatus(light);

    }

    onPress () {

        this[light.status].onPress();

    }

}

class Light {

    constructor () {

        this.status = 'offLightStatus';

    }

    // 切換狀態(tài)類

    setStatus (statusClass) {

        this.status = statusClass;

    }

}

// 抽象類

class LightStatus {

    constructor (light) {

        this.light = light;

    }

}

// 弱光

class WeakLightStatus extends LightStatus {

    constructor (light) {

        super(light);

    }

    onPress () {

        this.light.setStatus('strongLightStatus');

        console.log('開弱光燈');

    }

}

// 強(qiáng)光

class StrongLightStatus extends LightStatus {

    constructor (light) {

        super(light);

    }

    onPress () {

        this.light.setStatus('offLightStatus');

        console.log('開強(qiáng)光燈');

    }

}

// 關(guān)閉

class OffLightStatus extends LightStatus {

    constructor (light) {

        super(light);

    }

    onPress () {

        this.light.setStatus('weakLightStatus');

        console.log('關(guān)燈');

    }

}

const light = new Light();

const button = new Button(light);

button.onPress();

button.onPress();

button.onPress();

button.onPress();

通過(guò)重構(gòu)之后的代碼, 很明顯就是提供了代碼的可閱讀性, 可維護(hù)性.方便后續(xù)需求的擴(kuò)展,雖然會(huì)增加一定的代碼量.

現(xiàn)在我們通過(guò)對(duì)GOF書中對(duì)狀態(tài)模式的定義來(lái)加深自己的總結(jié):

允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)變化時(shí)候去改變它的行為, 對(duì)象似乎看起來(lái)改變了它的類

歸納分析:

把變化的屬性(狀態(tài))封裝成不同的類, 并把請(qǐng)求委托給當(dāng)前的對(duì)象狀態(tài), 不同的狀態(tài)此時(shí)執(zhí)行不同的行為

從使用者角度看, 我們使用的對(duì)象在不同狀態(tài)下有不同的行為, 彷佛這個(gè)對(duì)象是由不同類實(shí)例化而來(lái), 這是因?yàn)檎?qǐng)求委托的緣故.

模式結(jié)構(gòu)

狀態(tài)模式包含如下角色:

Context: 環(huán)境類

State: 抽象狀態(tài)類

ConcreteState: 具體狀態(tài)類

類比之前我們上述的實(shí)例場(chǎng)景: Context指的就是Button類. State指的就是LightStatus. ConcreteState指的就是各個(gè)不同狀態(tài)的類.

狀態(tài)模式描述了對(duì)象狀態(tài)的變化以及對(duì)象如何在每一種狀態(tài)下表現(xiàn)出不同的行為。

狀態(tài)模式的關(guān)鍵是引入了一個(gè)抽象類來(lái)專門表示對(duì)象的狀態(tài),這個(gè)類我們叫做抽象狀態(tài)類,而對(duì)象的每一種具體狀態(tài)類都繼承了該類,并在不同具體狀態(tài)類中實(shí)現(xiàn)了不同狀態(tài)的行為,包括各種狀態(tài)之間的轉(zhuǎn)換。

在狀態(tài)模式結(jié)構(gòu)中需要理解環(huán)境類與抽象狀態(tài)類的作用:

環(huán)境類實(shí)際上就是擁有狀態(tài)的對(duì)象,環(huán)境類有時(shí)候可以充當(dāng)狀態(tài)管理器(State Manager)的角色,可以在環(huán)境類中對(duì)狀態(tài)進(jìn)行切換操作。

抽象狀態(tài)類可以是抽象類,也可以是接口,不同狀態(tài)類就是繼承這個(gè)父類的不同子類,狀態(tài)類的產(chǎn)生是由于環(huán)境類存在多個(gè)狀態(tài),同時(shí)還滿足兩個(gè)條件: 這些狀態(tài)經(jīng)常需要切換,在不同的狀態(tài)下對(duì)象的行為不同。因此可以將不同對(duì)象下的行為單獨(dú)提取出來(lái)封裝在具體的狀態(tài)類中,使得環(huán)境類對(duì)象在其內(nèi)部狀態(tài)改變時(shí)可以改變它的行為,對(duì)象看起來(lái)似乎修改了它的類,而實(shí)際上是由于切換到不同的具體狀態(tài)類實(shí)現(xiàn)的。由于環(huán)境類可以設(shè)置為任一具體狀態(tài)類,因此它針對(duì)抽象狀態(tài)類進(jìn)行編程,在程序運(yùn)行時(shí)可以將任一具體狀態(tài)類的對(duì)象設(shè)置到環(huán)境類中,從而使得環(huán)境類可以改變內(nèi)部狀態(tài),并且改變行為。

狀態(tài)模式的優(yōu)缺點(diǎn)

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

狀態(tài)模式定義的狀態(tài)-行為的對(duì)應(yīng)關(guān)系, 并將其封裝在一個(gè)類里面, 我們只需要擴(kuò)展具體狀態(tài)類就可以擴(kuò)展需求.

避免了Context類的代碼無(wú)限膨脹和過(guò)多的條件分支判斷.

Context類中的請(qǐng)求于具體狀態(tài)類的行為隔離互補(bǔ)影響.

缺點(diǎn):

如果狀態(tài)類很多, 需要不斷擴(kuò)展代碼量.

狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。

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

狀態(tài)模式的性能優(yōu)化點(diǎn)

管理State對(duì)像的創(chuàng)建與銷毀: 有兩種方式實(shí)現(xiàn). 1. 僅僅當(dāng)Satte對(duì)象需要的時(shí)候才去創(chuàng)建(節(jié)省內(nèi)存).這個(gè)適合與那些State對(duì)象比較龐大的情景. 2. 一開始就創(chuàng)建所有的State對(duì)象,適用于State對(duì)象不多,以及狀態(tài)頻繁切換使用的情景.

我們上面的例子是一開始就創(chuàng)建了所有的State對(duì)象, 而且是為每一個(gè)Context類實(shí)例都創(chuàng)建了一組State對(duì)象,實(shí)際上我們這些State對(duì)象是可以在不同的Context類之間進(jìn)行共享的(享元模式,后續(xù)再擴(kuò)展說(shuō)這一塊).

適用環(huán)境

對(duì)象的行為依賴于它的狀態(tài)(屬性)并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。

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

感謝各位的閱讀!關(guān)于“java設(shè)計(jì)模式之狀態(tài)模式的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!


名稱欄目:java設(shè)計(jì)模式之狀態(tài)模式的示例分析
URL分享:http://weahome.cn/article/psccsi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部