设计模式之----状态模式(State-pattern)的理解
文章目錄
- 1.前言
- 2.概念
- 3.模式的結(jié)構(gòu)和實(shí)現(xiàn)
- 3.1 模式的結(jié)構(gòu)
- 3.2模式的實(shí)現(xiàn)
1.前言
在現(xiàn)實(shí)生活中,人都有高興和傷心的時(shí)候,不同的時(shí)候有不同的行為,有狀態(tài)的對(duì)象編程中高興,傷心可以看成一種狀態(tài),傳統(tǒng)的解決方案是:人的不同時(shí)候的行為都要考慮到的話,然后使用 if-else 或 switch-case 語(yǔ)句來(lái)做狀態(tài)判斷,再進(jìn)行不同情況的處理。這樣代碼會(huì)會(huì)過(guò)于臃腫,可讀性差,且不具備擴(kuò)展性,維護(hù)難度也大。且增加新的狀態(tài)時(shí)要添加新的 if-else 語(yǔ)句,這違背了“開閉原則”,不利于程序的擴(kuò)展。
2.概念
狀態(tài)模式的定義:對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。狀態(tài)模式的思想是:當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過(guò)于復(fù)雜時(shí),把相關(guān)“判斷邏輯”提取出來(lái),用各個(gè)不同的類進(jìn)行表示,系統(tǒng)處于哪種情況,直接使用相應(yīng)的狀態(tài)類對(duì)象進(jìn)行處理,這樣能把原來(lái)復(fù)雜的邏輯判斷簡(jiǎn)單化,消除了 if-else、switch-case 等冗余語(yǔ)句,代碼更有層次性,并且具備良好的擴(kuò)展力。
3.模式的結(jié)構(gòu)和實(shí)現(xiàn)
狀態(tài)模式把受環(huán)境改變的對(duì)象行為包裝在不同的狀態(tài)對(duì)象里,其目的是讓一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候,其行為也隨之改變?,F(xiàn)在我們來(lái)分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法。
3.1 模式的結(jié)構(gòu)
狀態(tài)模式包含以下主要角色。
3.2模式的實(shí)現(xiàn)
場(chǎng)景:這個(gè)場(chǎng)景大家都很熟悉,鼠標(biāo)進(jìn)去某個(gè)元素,會(huì)有個(gè)高亮的樣式,當(dāng)鼠標(biāo)點(diǎn)擊這個(gè)元素的時(shí)候,會(huì)有個(gè)選中的樣式,再次點(diǎn)擊選中狀態(tài)樣式消失,當(dāng)鼠標(biāo)離開元素,元素沒有樣式
簡(jiǎn)單分析下,這里的話會(huì)有4個(gè)狀態(tài),正常狀態(tài)(無(wú)樣式),高亮狀態(tài)(懸浮樣式),選中狀態(tài)(選中樣式),高亮選中狀態(tài)(懸浮加選中樣式),并且一個(gè)狀態(tài)進(jìn)入另一個(gè)狀態(tài)是有條件的,看下圖
按需求畫出類圖
1.首先創(chuàng)建一個(gè)抽象類ElementStatus
2.分別創(chuàng)建ElementNormalState類(正常狀態(tài)),ElementHightLightState類(高亮狀態(tài)),ElementHightLightSelectState類(高亮選中狀態(tài)),ElementSelectState類(選中狀態(tài))和構(gòu)建這些狀態(tài)的StateFactory類(工廠)
//ElementNormalState.ts 正常狀態(tài) import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementNormalState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "正常狀態(tài)";}public calculateState(eventName: string):ElementStatus {if (eventName == "mouseEnter") {return StateFactory.getElementStatus("ElementHightLightState");}throw new Error("現(xiàn)在是正常狀態(tài),切換不了其他狀態(tài)");} }//ElementHightLightState.ts 高亮狀態(tài) import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementHightLightState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "高亮狀態(tài)";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseLeaver") {return StateFactory.getElementStatus("ElementNormalState");} else if (eventName == "mouseClick") {return StateFactory.getElementStatus("ElementHightLightSelectState");}throw new Error("現(xiàn)在是高亮狀態(tài),切換不了其他狀態(tài)");} }//ElementHightLightSelectState.ts 高亮選中狀態(tài) import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementHightLightSelectState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "高亮選中狀態(tài)";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseLeaver") {return StateFactory.getElementStatus("ElementSelectState");} else if (eventName == "mouseClick") {return StateFactory.getElementStatus("ElementHightLightState");}throw new Error("現(xiàn)在是高亮選中狀態(tài),切換不了其他狀態(tài)")} }//ElementSelectState.ts 選中狀態(tài) import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory";export class ElementSelectState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "選中狀態(tài)";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseEnter") {return StateFactory.getElementStatus("ElementHightLightSelectState");}throw new Error("現(xiàn)在是選中狀態(tài),切換不了其他狀態(tài)");} }//StateFactory.ts 工廠類 import { ElementHightLightSelectState } from "./ElementHightLightSelectState"; import { ElementHightLightState } from "./ElementHightLightState"; import { ElementNormalState } from "./ElementNormalState"; import { ElementSelectState } from "./ElementSelectState"; export class StateFactory {public static getElementStatus(statusName: string): Status.ElementStatus {switch (statusName) {case "ElementNormalState":return new ElementNormalState();case "ElementHightLightState":return new ElementHightLightState();case "ElementHightLightSelectState":return new ElementHightLightSelectState();case "ElementSelectState":return new ElementSelectState();default:return new ElementNormalState();}} }3.創(chuàng)建ElementStatusContext類 管理這些狀態(tài)的類,設(shè)置默認(rèn)狀態(tài)是正常狀態(tài)
//ElementStatusContext.ts import { ElementNormalState } from "./ElementNormalState"; export class ElementStatusContext{public currentStatus: Status.ElementStatus;constructor() {this.currentStatus = new ElementNormalState();}public getStatus() {return this.currentStatus}public setStatus(status: Status.ElementStatus) {this.currentStatus = status;}public changeStatus(eventName: string): Status.ElementStatus {return this.currentStatus.calculateState(eventName);}}//Status.d.ts ts聲明文件 declare namespace Status {export type ElementStatus =import ("./ElementStatus").ElementStatus;export type ElementStatusContext =import ("./ElementStatusContext").ElementStatusContext;}4.最后IndexController 通過(guò)事件綁定好這些狀態(tài)并顯示在UI界面上
//Index.controller.ts import angular from "angular"; import { ElementStatusContext } from "./ElementStatusContext"; export class IndexController implements angular.IController {public static ElementStatusContext: Status.ElementStatusContext;public statusName: string;constructor() {IndexController.ElementStatusContext = new ElementStatusContext();this.statusName = IndexController.ElementStatusContext.getStatus().statusName;}//鼠標(biāo)進(jìn)入事件public mouseEnterEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseEnter");this.statusName = status.statusName}//鼠標(biāo)離開事件public mouseLeaveEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseLeaver");this.statusName = status.statusName}//colorElement點(diǎn)擊事件public colorElementClickEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseClick");this.statusName = status.statusName}//計(jì)算并設(shè)置狀態(tài)private calAndSetStatus(StatusContext: Status.ElementStatusContext, eventName: string) {let status = StatusContext.changeStatus(eventName);StatusContext.setStatus(status);return status;} }下面是 index.html ui界面
<!DOCTYPE html> <html lang="en" ng-app="myApp"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title> </head> <style>.element {width: 200px;height: 200px;border: 5px solid #ccc;margin: 0 auto;line-height: 200px;text-align: center;font-size: 20px;}.hight-light {background-color: greenyellow;}.select {border-color: green;}.hight-light-select {background-color: greenyellow;border-color: green;} </style><body ng-controller="IndexController as vm"><div class="element" ng-mouseenter="vm.mouseEnterEvent()" ng-mouseleave="vm.mouseLeaveEvent()"ng-click="vm.colorElementClickEvent()" ng-class="{'hight-light':vm.statusName=='高亮狀態(tài)','select':vm.statusName=='選中狀態(tài)','hight-light-select':vm.statusName=='高亮選中狀態(tài)'}">{{vm.statusName}}</div> </body> </html>最后看下效果圖:
總結(jié)優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
缺點(diǎn):
總結(jié)
以上是生活随笔為你收集整理的设计模式之----状态模式(State-pattern)的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 什么是南桥芯片和北桥芯片?南桥芯片和北桥
- 下一篇: dropbear 安装配置