博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
打造属于自己的设计模式
阅读量:6257 次
发布时间:2019-06-22

本文共 3949 字,大约阅读时间需要 13 分钟。

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

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

简单介绍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;
            
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);
        }

 行为实例:

View Code
 
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;
                
return 
false;
            }
        }

注册卡片:

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);
            }
        }
    }

根据自定义属性反射加载

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

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可以缓存任意多个实例。

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

部分代码

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;
        }  

 

 

 本文转自 熬夜的虫子  51CTO博客,原文链接:http://blog.51cto.com/dubing/712401

转载地址:http://dfisa.baihongyu.com/

你可能感兴趣的文章
大数据如何解决人工智能对文本挖掘的挑战
查看>>
updatepanel的属性
查看>>
.net 客户端调用java或.net webservice进行soapheader验证
查看>>
RadViz可视化方法--javascript实现
查看>>
软件工程综合实践的第二次实验报告
查看>>
Git储藏与恢复
查看>>
Lua 打印Table
查看>>
性能分析
查看>>
自定义php-mysqli工具增强类,支持链式调用
查看>>
SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础
查看>>
linux常用命令总结-updating
查看>>
SQL事务回滚样例
查看>>
AndFix注意事项
查看>>
Servlet、Filter、Listener、Interceptor
查看>>
SpringMVC源码分析系列
查看>>
SnakeWords开发--Android 2.2
查看>>
zookeeper的python客户端安装
查看>>
LINUX 下Open cv练习使用小记(2)
查看>>
JavaScript基础避免使用eval()(006)
查看>>
面向对象和面向过程的区别
查看>>