打造属于自己的设计模式

设计模式 一般初级、中级、高级程序员都喜欢挂在嘴边的词。想必大家身边也有不少关于设计模式的书。设计模式是程序员的老前辈们根据自己的项目经验积累起来的解决方案集。所以,没必要把设计模式看成是硬性的东西,别人的经验参考一下即可,了解设计思路,为什么这种场景要用这种模式。也许是老一辈的程序员们确实比现在的程序员要强很多,毕竟现在网上很难找到自己摸索的设计模式了。

虫子不才就先抛砖引玉了。

简单介绍2个我项目中经常用到的模式

1.机器人插件模式

何所谓机器人插件,可以这样理解。你有一个机器人,但是需要这个机器人干什么并不确定。插入不同的卡片可以让机器人做出不同的行为。原理和aop类似,aop是站在系统级的角度,插件模式基于行为。

直接看代码

定义行为:

ExpandedBlockStart.gif 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;
             if (tmp !=  null)
                tmp( this, e);
        }

         public  static  event EventHandler<EventArgs> bhedRobot;
         ///   <summary>
        
///  机器人行动后触发
        
///   </summary>
         protected  virtual  void OnbhedRobot(EventArgs e)
        {
            EventHandler<EventArgs> tmp = bhedRobot;
             if (tmp !=  null)
                tmp( this, e);
        }

         public  static  event EventHandler<ServingEventArgs> ServingRobot;
         ///   <summary>
        
///  调用机器人行为时触发
        
///   </summary>
         protected  virtual  void OnServing(ServingEventArgs e)
        {
            EventHandler<ServingEventArgs> tmp = ServingRobot;
             if (tmp !=  null)
                tmp( this, e);
        }

 行为实例:

ExpandedBlockStart.gif View Code
  public  bool bhRobot( out  string Message)
        {
            Message =  string.Empty;
            RobotCancelEventArgs e =  new RobotCancelEventArgs();
            OnServing(e);
             if (!e.Cancel)
            {
                var v = RobotService.bhRobot( thisout Message);

                 if (v)
                {
                    OnbhedRobot(EventArgs.Empty);
                     return  true;
                }
                 return  false;
            }
             else
            {
                Message = e.Message;
                 return  false;
            }
        }

注册卡片:

ExpandedBlockStart.gif View Code
 [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);
            }
        }
    }

根据自定义属性反射加载

ExpandedBlockStart.gif View Code
  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的方法,让外部来访问这个类的唯一实例。

ExpandedBlockStart.gif View Code
  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可以缓存任意多个实例。

也可以做得更通用一点,将单例的似有构造函数公开。实例的排他性通过对象锁来实现

部分代码

ExpandedBlockStart.gif View Code
  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;
        }  

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值