設計模式學習之01狀態模式

来源:http://www.cnblogs.com/kim-meng/archive/2016/11/15/6064699.html
-Advertisement-
Play Games

主體思想:狀態決定行為。 應用環境:同一對象,在狀態轉換過程中,行為隨著狀態一直在改變。 e.g. 燈初始狀態是關閉的,按一下開啟,再按一下關閉(不要跟我說你家的水晶變色大燈)。在這一個過程中,觸發行為都是按一下開關,電燈會根據自身狀態的不同調用不同的行為去實現。如果我們不適用設計模式去實現著這段邏 ...


主體思想:狀態決定行為。

應用環境:同一對象,在狀態轉換過程中,行為隨著狀態一直在改變。

e.g.  燈初始狀態是關閉的,按一下開啟,再按一下關閉(不要跟我說你家的水晶變色大燈)。在這一個過程中,觸發行為都是按一下開關,電燈會根據自身狀態的不同調用不同的行為去實現。如果我們不適用設計模式去實現著這段邏輯,一般就是這兩種實現方法吧

1.

if(燈狀態==XXX)
{
....
}
else
{
XXXXXXXX
}

2.

switch(燈狀態)
{
case XX:
     Xxxxxx
      break;
case  vv:
       vvvvvvvv
       break;
default:
       llllll
}

目前就是燈打開,關閉兩個狀態,咱們當然可以用這種if ,switch的方式來做。 如果實體對象狀態很多的話,採用上面判斷的方式,一個類方法的代碼就老長老長了。ok ,那麼咱們採用狀態模式來看看,該如何實現。

1.分析需求,設計類

狀態模式,毫無疑問,咱們需要實體類(Light),狀態類(LightState)。由於狀態類,會有不同狀態,相同的按燈動作。因此我們這麼設計。

抽象狀態類:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace DesignModel_01
 8 {
 9   abstract   class  LightState
10     {
11        public abstract  void PushClick(Light light);
12     }
13 }

實體類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignModel_01
{
    class Light
    {
        private LightState state;
       public  Light(LightState state)
        {
            this.State = state;
        }

        public LightState State
        {
            get
            {
                return state;
            }

            set
            {
                state = value;
            }
        }
        public void LightClick()
        {
            this.state.PushClick(this);
        }
    }
}

好了,主要工作完成,下麵就是具體燈的那個狀態了。目前就兩種狀態,打開關閉。

LightOn 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignModel_01
{
    class LightOn : LightState
    {
        public override void PushClick(Light light)
        {
            Console.WriteLine("燈正在關閉ing...");
            light.State = new LightOff();
            Console.WriteLine("燈已經關閉...");
        }
    }
}


LightOff 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignModel_01
{
    class LightOff : LightState
    {
        public override void PushClick(Light light)
        {
            Console.WriteLine("燈正在打開ing...");
            light.State = new LightOpen();
            Console.WriteLine("燈已經打開...");
        }
    }
}

測試man:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignModel_01
{
    class Program
    {
        static void Main(string[] args)
        {

            Light l = new Light(new LightOpen());
            for (int i = 0; i < 10; i++)
            {

                l.LightClick();
            }
            Console.ReadLine();
        }

    
    }
}

 

 

好吧,打臉了。。。。代碼似乎比if,switch 判斷還多。所以應對不同的業務場景,我們還是要理智的採用不同的方案。

優點

    a 狀態模式將與特定狀態相關的行為局部化,並且將不同狀態的行為分割開來。

    b 所有狀態相關的代碼都存在於某個ConcereteState中,所以通過定義新的子類很容易地增加新的狀態和轉換。

    c 狀態模式通過把各種狀態轉移邏輯分不到State的子類之間,來減少相互間的依賴。

缺點

     a 導致較多的ConcreteState子類

適用場景

    a 當一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式來。

    b 一個操作中含有龐大的分支結構,並且這些分支決定於對象的狀態。

 

內容參考:

 

http://www.cnblogs.com/god_bless_you/archive/2010/06/06/1752517.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • urllib requets selenium的應用場景 cookie識別用戶身份和記錄用戶狀態 driver.get_cookies() 獲得cookie信息 add_cookie(cookie_dict) 向cookie添加會話信息 delete_cookie(name) 刪除特定(部分)的co ...
  • 上篇說到了 RabbitMQ 的安裝。 這次要在講案例之前,需要安裝PHP的AMQP擴展。不然可能會報以下兩個錯誤。 1.Fatal error: Class 'AMQPConnection' not found 2. Fatal error: Uncaught exception 'AMQPCon ...
  • RabbitMQ: 1、是實現AMQP(高級消息隊列協議)的消息中間件的一種。 2、主要是為了實現系統之間的雙向解耦而實現的。當生產者大量產生數據時,消費者無法快速消費,那麼需要一個中間層。保存這個數據。 一般提到 RabbitMQ 和消息,都會用到以下一些專有名詞: (1)生產(Producing ...
  • 閱讀目錄 前言 怎麼賣 領域服務的使用 回到現實 結語 閱讀目錄 前言 怎麼賣 領域服務的使用 回到現實 結語 一、前言 上篇中我們講述了“把商品賣給用戶”中的商品和用戶的初步設計。現在把剩餘的“賣”這個動作給做了。這裡提醒一下,正常情況下,我們的每一步業務設計都需要和領域專家進行溝通,儘可能的符合 ...
  • 一、概述 迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。 二、解決問題 迭代器模式就是提供一種遍歷元素的統一介面,用一致的方法遍歷聚合元素。試想,如果我們的聚合元素是用不同的方式實現的,有些用了數組,有些用了java的集合類,或者還有其他方式,當客戶端要遍歷這些元素 ...
  • 原文地址 序列圖主要用於展示對象之間交互的順序。 序列圖將交互關係表示為一個二維圖。縱向是時間軸,時間沿豎線向下延伸。橫向軸代表了在協作中各獨立對象的類元角色。類元角色用生命線表示。當對象存在時,角色用一條虛線表示,當對象的過程處於激活狀態時,生命線是一個雙道線。 消息用從一個對象的生命線到另一個對 ...
  • aop( aspect oriented programming ) 面向切麵編程,是對所有對象或者是一類對象編程 幾個重要的概念: 1.切麵(aspect):要實現的交叉功能,是系統模塊化的一個切麵或領域。如日誌記錄。 2.連接點:應用程式執行過程中插入切麵的地點,可以是方法調用,異常拋出,或者要 ...
  • 第一個FreeMarker程式 1. 建立一個普通的java項目:testFreeMarker 2. 引入freemarker.jar包 3. 在項目目錄下建立模板目錄:templates 4. 在templates目錄下,建立a.ftl模板文件,內容如下: 5. 建立com.sxt.test.fr ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...