全國電子音樂交流中心

從真實項目中摳出來的設計模式——第一篇:策略模式

dotNET跨平臺2019-12-01 14:51:46

有時候因為種種原因導致我們會寫出很多丑陋的代碼,比如趕工時,短暫性的偷懶,不會設計模式等等導致代碼沉積,一個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);

? ? ? ? }

? ? }

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

原文地址:http://www.cnblogs.com/huangxincheng/p/6347633.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

体彩19051627