日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式之----状态模式(State-pattern)的理解

發布時間:2023/12/20 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式之----状态模式(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 模式的結構

狀態模式包含以下主要角色。

  • 環境類(Context)角色:也稱為上下文,相當是所有狀態的管理者(manage)并負責具體狀態的切換。
  • 抽象狀態(State)角色:定義一個接口,用以封裝環境對象中的特定狀態所對應的行為,可以有一個或多個行為。
  • 具體狀態(Concrete State)角色:實現抽象狀態所對應的行為,并且在需要的情況下進行狀態切換。

  • 3.2模式的實現

    場景:這個場景大家都很熟悉,鼠標進去某個元素,會有個高亮的樣式,當鼠標點擊這個元素的時候,會有個選中的樣式,再次點擊選中狀態樣式消失,當鼠標離開元素,元素沒有樣式


    簡單分析下,這里的話會有4個狀態,正常狀態(無樣式),高亮狀態(懸浮樣式),選中狀態(選中樣式),高亮選中狀態(懸浮加選中樣式),并且一個狀態進入另一個狀態是有條件的,看下圖


    按需求畫出類圖


    1.首先創建一個抽象類ElementStatus

    export abstract class ElementStatus {public statusName: string;public abstract calculateState(eventName: string):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)的理解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。