设计模式之----状态模式(State-pattern)的理解
文章目錄
- 1.前言
- 2.概念
- 3.模式的結構和實現
- 3.1 模式的結構
- 3.2模式的實現
1.前言
在現實生活中,人都有高興和傷心的時候,不同的時候有不同的行為,有狀態的對象編程中高興,傷心可以看成一種狀態,傳統的解決方案是:人的不同時候的行為都要考慮到的話,然后使用 if-else 或 switch-case 語句來做狀態判斷,再進行不同情況的處理。這樣代碼會會過于臃腫,可讀性差,且不具備擴展性,維護難度也大。且增加新的狀態時要添加新的 if-else 語句,這違背了“開閉原則”,不利于程序的擴展。
2.概念
狀態模式的定義:對有狀態的對象,把復雜的“判斷邏輯”提取到不同的狀態對象中,允許狀態對象在其內部狀態發生改變時改變其行為。狀態模式的思想是:當控制一個對象狀態轉換的條件表達式過于復雜時,把相關“判斷邏輯”提取出來,用各個不同的類進行表示,系統處于哪種情況,直接使用相應的狀態類對象進行處理,這樣能把原來復雜的邏輯判斷簡單化,消除了 if-else、switch-case 等冗余語句,代碼更有層次性,并且具備良好的擴展力。
3.模式的結構和實現
狀態模式把受環境改變的對象行為包裝在不同的狀態對象里,其目的是讓一個對象在其內部狀態改變的時候,其行為也隨之改變?,F在我們來分析其基本結構和實現方法。
3.1 模式的結構
狀態模式包含以下主要角色。
3.2模式的實現
場景:這個場景大家都很熟悉,鼠標進去某個元素,會有個高亮的樣式,當鼠標點擊這個元素的時候,會有個選中的樣式,再次點擊選中狀態樣式消失,當鼠標離開元素,元素沒有樣式
簡單分析下,這里的話會有4個狀態,正常狀態(無樣式),高亮狀態(懸浮樣式),選中狀態(選中樣式),高亮選中狀態(懸浮加選中樣式),并且一個狀態進入另一個狀態是有條件的,看下圖
按需求畫出類圖
1.首先創建一個抽象類ElementStatus
2.分別創建ElementNormalState類(正常狀態),ElementHightLightState類(高亮狀態),ElementHightLightSelectState類(高亮選中狀態),ElementSelectState類(選中狀態)和構建這些狀態的StateFactory類(工廠)
//ElementNormalState.ts 正常狀態 import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementNormalState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "正常狀態";}public calculateState(eventName: string):ElementStatus {if (eventName == "mouseEnter") {return StateFactory.getElementStatus("ElementHightLightState");}throw new Error("現在是正常狀態,切換不了其他狀態");} }//ElementHightLightState.ts 高亮狀態 import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementHightLightState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "高亮狀態";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseLeaver") {return StateFactory.getElementStatus("ElementNormalState");} else if (eventName == "mouseClick") {return StateFactory.getElementStatus("ElementHightLightSelectState");}throw new Error("現在是高亮狀態,切換不了其他狀態");} }//ElementHightLightSelectState.ts 高亮選中狀態 import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory"; export class ElementHightLightSelectState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "高亮選中狀態";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseLeaver") {return StateFactory.getElementStatus("ElementSelectState");} else if (eventName == "mouseClick") {return StateFactory.getElementStatus("ElementHightLightState");}throw new Error("現在是高亮選中狀態,切換不了其他狀態")} }//ElementSelectState.ts 選中狀態 import { ElementStatus } from "./ElementStatus"; import { StateFactory } from "./StateFactory";export class ElementSelectState extends ElementStatus {public statusName: string;constructor() {super();this.statusName = "選中狀態";}public calculateState(eventName: string): ElementStatus {if (eventName == "mouseEnter") {return StateFactory.getElementStatus("ElementHightLightSelectState");}throw new Error("現在是選中狀態,切換不了其他狀態");} }//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.創建ElementStatusContext類 管理這些狀態的類,設置默認狀態是正常狀態
//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 通過事件綁定好這些狀態并顯示在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;}//鼠標進入事件public mouseEnterEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseEnter");this.statusName = status.statusName}//鼠標離開事件public mouseLeaveEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseLeaver");this.statusName = status.statusName}//colorElement點擊事件public colorElementClickEvent(): void {let status = this.calAndSetStatus(IndexController.ElementStatusContext, "mouseClick");this.statusName = status.statusName}//計算并設置狀態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=='高亮狀態','select':vm.statusName=='選中狀態','hight-light-select':vm.statusName=='高亮選中狀態'}">{{vm.statusName}}</div> </body> </html>最后看下效果圖:
總結優缺點
優點:
缺點:
總結
以上是生活随笔為你收集整理的设计模式之----状态模式(State-pattern)的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是南桥芯片和北桥芯片?南桥芯片和北桥
- 下一篇: asp.net配置文件connectio