天天看點

打造屬于自己的設計模式

設計模式 一般初級、中級、進階程式員都喜歡挂在嘴邊的詞。想必大家身邊也有不少關于設計模式的書。設計模式是程式員的老前輩們根據自己的項目經驗積累起來的解決方案集。是以,沒必要把設計模式看成是硬性的東西,别人的經驗參考一下即可,了解設計思路,為什麼這種場景要用這種模式。也許是老一輩的程式員們确實比現在的程式員要強很多,畢竟現在網上很難找到自己摸索的設計模式了。

蟲子不才就先抛磚引玉了。

簡單介紹2個我項目中經常用到的模式

1.機器人插件模式

何所謂機器人插件,可以這樣了解。你有一個機器人,但是需要這個機器人幹什麼并不确定。插入不同的卡片可以讓機器人做出不同的行為。原理和aop類似,aop是站在系統級的角度,插件模式基于行為。

直接看代碼

定義行為:

View Code

 public static event EventHandler<RobotCancelEventArgs> DeleteingRobot;

        protected virtual void OnDeleteingRobot(RobotCancelEventArgs e)

        {

            EventHandler<RobotCancelEventArgs> tmp = DeleteingRobot;

            if (tmp != null)

                tmp(this, e);

        }

        public static event EventHandler<RobotCancelEventArgs> bhingRobot;

        /// <summary>

        /// 機器人行動前觸發事件

        /// </summary>

        protected virtual void OnbhingRobot(RobotCancelEventArgs e)

            EventHandler<RobotCancelEventArgs> tmp = bhingRobot;

        public static event EventHandler<EventArgs> bhedRobot;

        /// 機器人行動後觸發

        protected virtual void OnbhedRobot(EventArgs e)

            EventHandler<EventArgs> tmp = bhedRobot;

        public static event EventHandler<ServingEventArgs> ServingRobot;

        /// 調用機器人行為時觸發

        protected virtual void OnServing(ServingEventArgs e)

            EventHandler<ServingEventArgs> tmp = ServingRobot;

 行為執行個體:

 public bool bhRobot(out string Message)

            Message = string.Empty;

            RobotCancelEventArgs e = new RobotCancelEventArgs();

            OnServing(e);

            if (!e.Cancel)

            {

                var v = RobotService.bhRobot(this, out Message);

                if (v)

                {

                    OnbhedRobot(EventArgs.Empty);

                    return true;

                }

                return false;

            }

            else

                Message = e.Message;

注冊卡片:

 [Extension("", "1.0", "熬夜的蟲子")]

    public class CardRobot

    {

        static CardRobot()

            Robot.ServingRobot += new EventHandler<ServingEventArgs>(Comment_ServingDelegate);

        static void Comment_ServingDelegate(object sender, ServingEventArgs e)

            try

              //do something

            catch (Exception ex)

                //Log4N.WarnLog("BadWordFilterExtension Exception:", ex);

    }

根據自定義屬性反射加載

 void Application_Start(object sender, EventArgs e) 

        ExtensionManager.InitExtension();

        System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));

        foreach (var item in di.GetFiles("*.dll", System.IO.SearchOption.TopDirectoryOnly))

            System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(item.FullName);

            Type[] types = assembly.GetTypes();

            foreach (Type type in types)

                object[] attributes = type.GetCustomAttributes(typeof(CommentEngine.Core.ExtensionAttribute), false);

                foreach (object attribute in attributes)

                    if (ExtensionManager.ExtensionIsEnable(type.Name))

                        assembly.CreateInstance(type.FullName);

2.單例擴充模式

先看看傳統的單例模式 撇開懶漢式等區分

負責建立Singleton類自己的唯一執行個體,并提供一個getInstance的方法,讓外部來通路這個類的唯一執行個體。

 public static T GetInstance(object lockKey, T instance, Func<T> onCreateInstance)

            if (instance == null)

                if (lockKey == null)

                    lockKey = LockKey;

                lock (lockKey)

                    if (instance == null)

                    {

                        try

                        {

                            if (onCreateInstance == null)

                                instance = new T();

                            else

                                instance = onCreateInstance();

                        }

                        catch

                            instance = default(T);

                    }

            return instance;

優點:節省系統資源。

适用場景:

當需要控制一個類的執行個體隻能有一個,而且客戶隻能從一個全局通路點通路它時,可以選用單例模式,這些功能恰好是單例模式要解決的問題。

擴充場景:

海量即時消息,消息處理機制含有複雜邏輯,體積龐大。這個時候你用單例模式可能導緻消息不即時,不用單例資源占用太大。

可能有人就會思考,能不能控制執行個體數目為2個,3個,或者是任意多個呢?目的都是一樣的,節約資源啊,有些時候單個執行個體不能滿足實際的需要,會忙不過來,根據測算,6個執行個體剛剛好。

思路很簡單,就是利用上面通過Map來緩存實作單例的示例,進行變形,一個Map可以緩存任意多個執行個體。

也可以做得更通用一點,将單例的似有構造函數公開。執行個體的排他性通過對象鎖來實作

部分代碼

 private static Hashtable<String, Example> map = new System.Collections.Hashtable();

        private static int flag = 1;  

        private static int MAX = 6;           

        public static Example getInstance()

            String value = "aoyedechongzi" + flag;

            Example Example = map.get(value);

            if (Example == null)

                Example = new Example();

                map.put(value, Example);

            flag++;

            if (flag > MAX)

                flag = 1;

            return Example;

        }  

 本文轉自 熬夜的蟲子  51CTO部落格,原文連結:http://blog.51cto.com/dubing/712401

繼續閱讀