善用設計模式改善我們醜陋的代碼——策略模式

来源:http://www.cnblogs.com/huangxincheng/archive/2017/01/24/6347633.html
-Advertisement-
Play Games

有時候因為種種原因導致我們會寫出很多醜陋的代碼,比如趕工時,短暫性的偷懶,不會設計模式等等導致代碼沉積,一個cs上萬行代碼這樣場景是有發生, 當然這裡也包括我。。。所以時間充裕一點之後就想重構一下,畢竟項目中的需求是不斷變更的,面對需求變更,儘量做到最低限度的修改代碼,最大化的擴充 新代碼,還有一點 ...


  有時候因為種種原因導致我們會寫出很多醜陋的代碼,比如趕工時,短暫性的偷懶,不會設計模式等等導致代碼沉積,一個cs上萬行代碼這樣場景是有發生,

當然這裡也包括我。。。所以時間充裕一點之後就想重構一下,畢竟項目中的需求是不斷變更的,面對需求變更,儘量做到最低限度的修改代碼,最大化的擴充

新代碼,還有一點就是不要過分的追求設計模式,做到適可為止,太設計模式了會導致類太多,不好管理,在項目開發中,其實仔細考慮一下,你會發現很多業

務邏輯都有相應的設計模式幫你優化,畢竟這些都是前輩們踩了無數的坑,經過無數的苦難留下來的智慧結晶。很多人列舉設計模式都喜歡用生活中的例子,但

畢竟生活中的例子如何應用到項目中,對我們程式員來說還是比較抽象的,所以這裡我就列舉我們實際的業務邏輯場景。

 

一:實際場景介紹

    我們在做千人千面的時候,為了防止各大郵箱服務商對我們的郵件營銷內容做屏蔽處理,我們採用的策略就是眾多模板庫中隨機抽取一封html樣式表,然後結

合具體的商品列表生成完全不一樣風格的營銷內容郵件,爭取最大可能的不被屏蔽,而用戶自己通過我們系統做的營銷郵件,我們又不能隨機發送,而是用戶生成

什麼樣的郵件,我們就發什麼樣的郵件,ok,現在這裡就有兩種策略場景了,兩種場景的最終目的都是生成郵件內容,對吧。

 

1. 普通商家做營銷活動的郵件,這種策略沒什麼好說的,是什麼就發什麼。

2.千人千面場景下的營銷活動郵件,這種策略採用隨機抽取的模式,

 

目前來說,我們就這兩種場景,誰也指不定以後還會不會有其他的策略出來,所以有必要用策略模式玩一下。

 

二:構建UML

    從vs2005開始就有一個強大的功能,根據cs文件自動生成uml類圖,非常的直觀也更容易的幫助我們設計更加合理的類圖。

 

上面就是策略模式的uml圖,各個策略類中都有一個Setup方法,用來設置email的內容,具體各個類中的代碼如下:

 

<1> AbstractStrategy

    public abstract class AbstractStrategy
    {
        public abstract void Setup();
    }

 

<2> RandStrategy

    public class RandStrategy : AbstractStrategy
    {
        public override void Setup()
        {
            Console.WriteLine("千人千面模式下的郵件發送");
        }
    }

 

<3> StraightStrategy 

    public class StraightStrategy : AbstractStrategy
    {
        public override void Setup()
        {
            Console.WriteLine("普通商家發送的郵件");
        }
    }

 

<4>StrategyContext

    public class StrategyContext
    {
        AbstractStrategy strategy = null;

        public void SetStrategy(AbstractStrategy strategy)
        {
            this.strategy = strategy;
        }

        public void Setup()
        {
            this.strategy.Setup();
        }
    }

 

<5> Program

    class Program
    {
        static void Main(string[] args)
        {
            StrategyContext context = new StrategyContext();

            //設置“隨機策略“
            context.SetStrategy(new RandStrategy());

            context.Setup();

            //設置 ”直接發送“
            context.SetStrategy(new StraightStrategy());

            context.Setup();
        }
    }

 

最後我們運行一下:

 

上面就是一個最簡單的策略模式,當我們設置不同的策略,就會執行相應的行為,實際當中,並不會這麼簡單,畢竟設計模式只是一個最優化的提煉,排除干擾看本質。

 

三:生產應用

   首先生產中我們的AbstractSetup中的Setup方法肯定是要帶有參數的,而不是簡單的無參,如下:

    /// <summary>
    /// 簡訊,郵件,彩信設置模型
    /// </summary>
    public abstract class AbstractSetup
    {
        public abstract void Setup(LeafletEntity leaflet, DataRow row);
    }

 

然後直接賦值的邏輯也非常的簡單,需要根據資料庫中設置的業務邏輯判斷。

   public class StraightSetup : AbstractSetup
    {
        public override void Setup(LeafletEntity leaflet, DataRow row)
        {
            //非顧問
            leaflet.Title = MySqlDbHelper.GetString(row, "title");

            leaflet.SMSContent = leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.簡訊) ? MySqlDbHelper.GetString(row, "content") : string.Empty;
            leaflet.EDMContent = leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.郵件) ? MySqlDbHelper.GetString(row, "content") : string.Empty;
            leaflet.MMSContent = leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信) ? MySqlDbHelper.GetString(row, "content") : string.Empty;

            leaflet.SendSMSCount = Convert.ToInt32(row["sendcount"]);
        }
    }

 

接下來就是隨機抽取邏輯,這個也是通過讀取隨機表來進行各種操作,簡單的代碼如下:

  public class RandSetup : AbstractSetup
    {
        EventMarketingBLLNew eventMarketingBLLNew = new EventMarketingBLLNew();

        public override void Setup(LeafletEntity leaflet, DataRow row)
        {
            var eventMarketingInfo = eventMarketingBLLNew.GetEventMarketingInfo(leaflet.MarketingID, leaflet.ShopID);

            if (eventMarketingInfo != null)
            {
                //“簡訊”和“郵件”信息
                var communicationInfo = eventMarketingInfo.EventmarketingSmsEdmContentList.OrderBy(m => Guid.NewGuid())
                                                          .FirstOrDefault();

                if (communicationInfo == null) return;

                if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.郵件))
                {
                    //第三步:動態生成郵件模板
                    var styleInfo = CacheUtil.GetRandomEmailStyle();

                    var tuple = new EdmDraftBoxBLL().GetEdmHtmlTitle(communicationInfo.EDMJson, styleInfo.StyleId);

                    leaflet.Title = tuple.Item1;
                    leaflet.EDMContent = tuple.Item2;
                    leaflet.Header = tuple.Item3;
                    leaflet.SendSMSCount = 1;
                }

                if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.簡訊))
                {
                    leaflet.SMSContent = communicationInfo.SMSContent;
                    leaflet.SendSMSCount = communicationInfo.SMSCount;
                }

                if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信))
                {
                    leaflet.MMSContent = communicationInfo.MMSContent;
                }
            }
        }
    }

 

最後就是策略上下文:

    public class SetupContext
    {
        AbstractSetup abstractSetup = null;

        public void Set(AbstractSetup abstractSetup)
        {
            this.abstractSetup = abstractSetup;
        }

        public void Setup(LeafletEntity leaflet, DataRow row)
        {
            this.abstractSetup.Setup(leaflet, row);
        }
    }

 

好了,這個就是給大家演示的策略模式,簡單來說就是一句話:針對同一命令或行為,不同的策略做不同的動作。 

 


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

-Advertisement-
Play Games
更多相關文章
  • 前段時間,聽了一堂C語言的課,那老師說:“數組名就是一個指向數組首地址的常量指針”。 我上百度查了一些,有好多教程、書籍等,都持相同的觀點。 但我一直感覺——數組名不等於指針。 實踐是檢驗真理的唯一標準,於此,有了以下內容。 首先,聲明一個數組和一個常量指針並指向那個數組。 設問:一個整型指針的長度 ...
  • 閱讀目錄 前言 解決數據一致性的方案 回到DDD 設計 實現 結語 一、前言 之前的十一篇把用戶購買商品並提交訂單整個流程上的中間環節都過了一遍。現在來到了這最後一個環節,提交訂單。單從業務上看,這個動作的背後包含了多個業務操作,根據用戶填寫的訂單信息生成訂單、扣除使用的餘額和積分、使用選擇的禮券等 ...
  • 不要誤會,我不是針對python,也不是針對nodejs,我是說除了.NET之外,玩爬蟲的都是垃圾 ...
  • ddd小白,一篇章節便能激起了心中漣漪,感慨之初,記於筆下。 第1章 消化知識 用醍醐灌頂、茅塞頓開來形容此章短短的文字,實不為過。 簡單介紹背景:旅游互聯網,B2B,初創公司。產品設計-代碼開發的銜接有過兩種明顯形式: 1. 項目的推進由產品部起頭,收集、分析、過濾需求,形成原型文檔(word,e ...
  • 代理模式在java中的使用,包括靜態代理和動態代理,對retrofit進行模擬 ...
  • 開發框架要考慮的面太多了:安全、穩定、性能、效率、擴展、整潔,還要經得起實踐的考驗,從零開發一個可用的框架,是很耗時費神的工作。網上很多開源的框架,為何還要自己開發?我是基於以下兩點: 1. 沒找到合適的:安全、穩定、簡單、易用、高效、免費; 2. 想成為架構師; 於是就自己動手,參考網上開源的項目 ...
  • ICO (input current optimizer) 手機接上 adapter 後, 手機裡的 charger IC bq25896 開始向 adapter 抽取 current 供給 battery 充電 及 系統消耗,( 這裡的電路圖是假設 adapter 直接接到 charger IC ...
  • 上海修剪園林之風,始於明代。嘉靖三十八年,又有幾處破土動工。 申家祖上並無淵源,到了這一代,長子當過一任太守,卸任回家,造了座園林“萬竹村”。弟弟申明世喜中進士,哥哥在申家地盤上為他另建一個園子。此處用佃戶種桃,桃花爛漫,名“天香園”。園子尚未建成,明世拜別父母兄長與一妻一妾,帶著新娶的小妾去江西赴 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...