博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不懂设计模式
阅读量:7079 次
发布时间:2019-06-28

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

本篇是讲设计模式方面的,比较杂,不像书上的那样。

我们先从很简单的一个需求开始:“想让系统中只存在一个SendEmailObject对象”

代码:

public class SendEmailObject    {        public bool Send()        {            Console.WriteLine("Email sent from : "+this.GetHashCode());       //加这个GetHashCode调用是用来查看instance是否同一个的            return false;        }    }    public static class Factory    {        private static SendEmailObject sendEmail;        public static SendEmailObject GetSendEmailObject()        {            if (sendEmail == null)            {                lock (typeof(SendEmailObject))              //加了个锁                {                    if (sendEmail == null)                        sendEmail = new SendEmailObject();                }            }            return sendEmail;        }    }

 main函数中调用代码:

var o = Factory.GetSendEmailObject();            o.Send();            o = Factory.GetSendEmailObject();            o.Send();            Console.Read();

 运行后:

 上面的代码由于和具体的类"SendEmailObject"强耦合了,因此不够通用,要是我需要有很多个类都需要这样来控制instance数量的话,就要复制黏贴很多很多code了,所以看下面的改进:

支持泛型的方法(更通用)

代码:

public static class Factory    {        private static Dictionary
instances = new Dictionary
(); public static T GetInstance
() where T : class, new() { T o = null; if (instances.ContainsKey(typeof(T))) o = instances[typeof(T)] as T; if (o == null) { lock (instances) { if (instances.ContainsKey(typeof(T))) o = instances[typeof(T)] as T; if (o == null) { o = new T(); instances[typeof(T)] = o; } } } return o; } public static int GetInstanceCount() //这个方法只是测试用的,真正用的时候要去掉 { return instances.Count; } }

 

 main调用代码:

var o = Factory.GetInstance
(); o.Send(); o = Factory.GetInstance
(); o.Send(); o = Factory.GetInstance
(); o.Send(); o = Factory.GetInstance
(); o.Send(); Console.WriteLine("Factory instance count: " + Factory.GetInstanceCount()); Console.Read();

 

运行后:

看最后一行输出,instance数只要一个。哈哈,通用性搞定拉...

 

上面说的都是要求只要一个instance的情况,要是这个需求呢?“由于SendEmailObject类很重,同时考虑到性能,因此需要做到:方便的访问+控制instance数量+多个instance同时处理request”,请看下面的方法:

能控制instance数量(max)的方法,代码如下:

public static class Factory    {        private static int MaxInstancePerType = 3;  //此处设置了最多3个instance        private static Dictionary
> instances = new Dictionary
>(); //instance队列 private static Dictionary
instanceCounters = new Dictionary
(); //instance相应的计数器队列 public static T GetInstance
() where T : class, new() { lock (instances) //锁定对象 { if (!instances.ContainsKey(typeof(T))) { List
tmplist = new List(); for (int i = 0; i < MaxInstancePerType; i++) { T o = new T(); tmplist.Add(o); } instances.Add(typeof(T), tmplist); instanceCounters.Add(typeof(T), 0); } List list = instances[typeof(T)] as List; int curIndex = instanceCounters[typeof(T)]; T instance = list[curIndex] as T; curIndex++; curIndex = curIndex % MaxInstancePerType; //循环取模 instanceCounters[typeof(T)] = curIndex; return instance; } } }

 

main调用代码:

SendEmailObject o;            for (int i = 0; i < 10; i++)            {                o = Factory.GetInstance
(); o.Send(); } Console.Read();

 

运行如下:

哈哈,上面的输出是循环的,3个一组的循环

 

下面我们来点题外话,有人说:“这个object怎么没有接口?” ,那好,那就加一个吧,如下:

public interface IEmailService        //新增加的接口    {        bool Send();    }    public class SendEmailObject : IEmailService    {        public bool Send()        {            Console.WriteLine("Email sent from : "+this.GetHashCode());            return false;        }    }

 

有人说,我想实现这个需求:“我提供一个interface, 工厂返回一个instance”,ok,没问题,写写吧,代码:

public static class Factory    {        private static Dictionary
typeMappers = new Dictionary
(); public static void Register
() where N : class, new() { if (typeMappers.ContainsKey(typeof(M))) throw new Exception("Key existed"); typeMappers.Add(typeof(M), typeof(N)); } public static M Resolve
() { if (!typeMappers.ContainsKey(typeof(M))) throw new Exception("Key empty, register please"); Type type = typeMappers[typeof(M)]; return (M)Activator.CreateInstance(type); } }

 

main调用代码:

Factory.Register
(); IEmailService srv = Factory.Resolve
();srv.Send();
srv = Factory.Resolve
();srv.Send();
Console.Read();

 

运行输出:

看看,哦,不对啊,这是2个instance啊?! 哈哈,对的,是2个instance,因为上面的代码里没有控制instance的数量,有兴趣的兄弟改改发不发布吧,哈哈。

哦,对了,上面的代码是不是很想Unity的Resolve和StructureMap的Resolve方法?哈哈。

囧:上面的代码是设计模式的哪种,偶是分不清的...哈哈

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

你可能感兴趣的文章
spark 共享变量
查看>>
用于字符输入的流成员函数使用举例
查看>>
我的友情链接
查看>>
Android ZoomControls缩放控件
查看>>
phpwind论坛搭建
查看>>
关于 51CTO家园无忧币领取制度的调整公告
查看>>
拥有丰富经验的移动广告聚合平台-KeyMob
查看>>
ActiveMQ(三)消息机制
查看>>
CentOS yum安装mcrypt详细图解教程
查看>>
我的友情链接
查看>>
FastDFS 安装部署
查看>>
我的友情链接
查看>>
查看命令帮助 help 、man
查看>>
Linux下Squid正向/反向代理配置
查看>>
android sdk 更新代理
查看>>
企业快速开发的优点
查看>>
WIN7 64位系统使用SCRT 7.064位、GNS3以及SCRT与GNS3的关联(一)
查看>>
MONGO_URL
查看>>
监控服务器Nagios之三 监控案例
查看>>
最简单的jdbc程序
查看>>