文章出處

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

 

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

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()