新聞中心
狀態(tài)模式是一個(gè)有趣的模式,它可能是解決一些需求場(chǎng)景的最佳方式。雖然狀態(tài)模式不是一種易于學(xué)習(xí)的模式(它通常會(huì)導(dǎo)致代碼量增加),但一旦您了解了狀態(tài)模式的本質(zhì),您將在未來(lái)感謝它無(wú)與倫比的好處。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),湖濱企業(yè)網(wǎng)站建設(shè),湖濱品牌網(wǎng)站建設(shè),網(wǎng)站定制,湖濱網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,湖濱網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M(mǎn)足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
網(wǎng)上很多文章在解釋狀態(tài)模式時(shí),都過(guò)于理論化,難以理解。這里我嘗試用一個(gè)實(shí)際案例用通俗易懂的方式來(lái)解釋。
01、打開(kāi)/關(guān)閉燈?
讓我們想象一個(gè)場(chǎng)景,其中有一盞燈只有一個(gè)開(kāi)關(guān)。
- 燈亮?xí)r按下開(kāi)關(guān),燈將關(guān)閉。
- 再按一下開(kāi)關(guān),燈就亮了。
我們可以發(fā)現(xiàn)一個(gè)特點(diǎn):同一個(gè)開(kāi)關(guān)按鈕在不同的狀態(tài)下會(huì)有不同的行為。
現(xiàn)在讓我們編寫(xiě)一段代碼來(lái)模擬燈光,并打開(kāi)和關(guān)閉燈光,如何編寫(xiě)代碼?
一個(gè)簡(jiǎn)單的實(shí)現(xiàn):
class Light{
constructor() {
this.state = 'off'
}
clickButton() {
if (this.state === 'off') {
console.log('turn on the light')
this.state = 'on'
} else if (this.state === 'on') {
console.log('turn off the light')
this.state = 'off'
}
}
}
用法:
02、多態(tài)
在上面的場(chǎng)景中,燈只有兩種狀態(tài),所以代碼寫(xiě)起來(lái)比較簡(jiǎn)單。
但我們需要知道,在現(xiàn)實(shí)生活中,很多物體都有兩種以上的狀態(tài),一旦一個(gè)對(duì)象有更多的狀態(tài),它就會(huì)更麻煩。
例如,有些手電筒具有三種狀態(tài):
- 關(guān)閉狀態(tài)
- 弱光狀態(tài)
- 強(qiáng)光狀態(tài)?
第一次按下開(kāi)關(guān)打開(kāi)弱光,第二次按下打開(kāi)強(qiáng)光,第三次按下關(guān)閉燈。
現(xiàn)在讓我們模擬這樣的行為,我們應(yīng)該如何寫(xiě)代碼?
03、正常解決方案
正常的解決方案是擴(kuò)展前面的代碼,在clickButton方法中進(jìn)行一些額外的狀態(tài)判斷和狀態(tài)切換。
class Light{
constructor() {
this.state = 'off'
}
clickButton() {
if (this.state === 'off') {
console.log('Turn on the low light')
this.state = 'lowLight'
} else if (this.state === 'lowLight') {
console.log('Switch to the strong light')
this.state = 'strongLight'
} else if (this.state === 'strongLight') {
console.log('turn off the light')
this.state = 'off'
}
}
}
雖然這樣的代碼可以滿(mǎn)足要求,但它有很多缺點(diǎn)。
- 如果以后需要添加或者修改Light的狀態(tài),那么就需要不斷的修改clickButton方法,使得clickButton不穩(wěn)定,不符合開(kāi)閉原則。
- 同時(shí),所有與狀態(tài)相關(guān)的行為都放在了clickButton方法中,不符合單一職責(zé)原則。如果以后加入新的狀態(tài),比如superStrongLight,clickButton方法會(huì)越來(lái)越臃腫。
- 最后,狀態(tài)之間的切換完全依賴(lài)于在 clickButton 方法中堆疊 if 和 else 語(yǔ)句。添加或修改狀態(tài)可能需要更改多個(gè)操作,這使得該方法更難以閱讀和維護(hù)。
04、分析
讓我們回想一下,我們的代碼使用 Light 作為一個(gè)單獨(dú)的對(duì)象,然后它具有三種狀態(tài)。然后我們需要讓它在不同的狀態(tài)之間切換,我們將不同的狀態(tài)視為光的內(nèi)部屬性。
但實(shí)際上,我們可以打破慣性思維,將每一個(gè)狀態(tài)都視為一個(gè)獨(dú)立的存在,封裝成一個(gè)單獨(dú)的類(lèi)。
比如這里的燈有三種狀態(tài):
- 低光狀態(tài)
- 強(qiáng)光狀態(tài)
- 關(guān)閉狀態(tài)
不同狀態(tài)的燈有自己的行為特征。
LowLightState 的clickButton 方法將狀態(tài)切換為StrongLightState,StrongLightState 的clickButton 將狀態(tài)切換為OffState。
而我們的Light只需要關(guān)注它處于什么狀態(tài),不需要處理狀態(tài)切換,狀態(tài)切換由每個(gè)狀態(tài)自己處理。
這是完整的代碼:
class OffLightState{
constructor(light) {
this.light = light
}
clickButton() {
console.log('Turn on the low light')
this.light.setState(this.light.lowLightState)
}
}
class LowLightState {
constructor(light) {
this.light = light
}
clickButton() {
console.log('Switch to the strong light')
this.light.setState(this.light.strongLightState)
}
}
class StrongLightState {
constructor(light) {
this.light = light
}
clickButton() {
console.log('turn off the light')
this.light.setState(this.light.offLightState)
}
}
class Light{
constructor() {
this.offLightState = new OffLightState(this);
this.lowLightState = new LowLightState(this);
this.strongLightState = new StrongLightState(this);
this.currentState = this.offLightState
}
setState(newState) {
this.currentState = newState
}
clickButton() {
this.currentState.clickButton()
}
}
let light = new Light()
light.clickButton()
light.clickButton()
light.clickButton()
圖中解釋?zhuān)?/p>
這樣的代碼可以解決前面提到的問(wèn)題:
輕物體更簡(jiǎn)單。它只需要調(diào)用this.currentState.clickButton(),狀態(tài)切換可以由狀態(tài)對(duì)象自己處理。
如果將來(lái)有新的狀態(tài),我們只需要?jiǎng)?chuàng)建一個(gè)新的狀態(tài)類(lèi),然后修改其相鄰的狀態(tài)類(lèi),而不需要對(duì)現(xiàn)有代碼進(jìn)行大量修改。
這種編寫(xiě)代碼的技術(shù)就是狀態(tài)模式。
05、狀態(tài)模式
狀態(tài)模式的正式定義:
狀態(tài)模式是一種行為軟件設(shè)計(jì)模式,它允許對(duì)象在其內(nèi)部狀態(tài)發(fā)生變化時(shí)改變其行為。這種模式接近于有限狀態(tài)機(jī)的概念。狀態(tài)模式可以解釋為策略模式,它能夠通過(guò)調(diào)用模式接口中定義的方法來(lái)切換策略。?
簡(jiǎn)單來(lái)說(shuō),如果你的對(duì)象有多個(gè)狀態(tài),并且不同狀態(tài)的對(duì)象表現(xiàn)不同,那么你可以考慮使用狀態(tài)模式。
狀態(tài)模式有時(shí)會(huì)增加代碼行數(shù),但代碼的質(zhì)量并不取決于代碼行數(shù)。使用狀態(tài)模式通??梢允鼓膶?duì)象的邏輯更加簡(jiǎn)潔。
總結(jié)
以上就是我今天與你分享的關(guān)于在JavaScript中使用狀態(tài)模式簡(jiǎn)化對(duì)象的全部?jī)?nèi)容,希望這些內(nèi)容對(duì)你有幫助,如果你覺(jué)得我今天的內(nèi)容有用的話(huà),請(qǐng)將它分享給你身邊的朋友,也許能夠幫助到他。
新聞標(biāo)題:如何用狀態(tài)模式優(yōu)化你的JavaScript代碼
當(dāng)前路徑:http://m.5511xx.com/article/djeegcd.html


咨詢(xún)
建站咨詢(xún)
