有時候因為種種原因導致我們會寫出很多醜陋的代碼,比如趕工時,短暫性的偷懶,不會設計模式等等導致代碼沉積,一個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); } }
好了,這個就是給大家演示的策略模式,簡單來說就是一句話:針對同一命令或行為,不同的策略做不同的動作。