不懂设计模式

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

我们先从很简单的一个需求开始:“想让系统中只存在一个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<Type, object> instances = new Dictionary<Type, object>();
        public static T GetInstance<T>()
            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<SendEmailObject>();
            o.Send();
            o = Factory.GetInstance<SendEmailObject>();
            o.Send();
            o = Factory.GetInstance<SendEmailObject>();
            o.Send();
            o = Factory.GetInstance<SendEmailObject>();
            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<Type, List<object>> instances = new Dictionary<Type, List<object>>();     //instance队列
        private static Dictionary<Type, int> instanceCounters = new Dictionary<Type, int>();                //instance相应的计数器队列
        public static T GetInstance<T>()
            where T : class, new()
        {
            lock (instances)    //锁定对象
            {
                if (!instances.ContainsKey(typeof(T)))
                {
                    List<object> tmplist = new List<object>();

                    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<object> list = instances[typeof(T)] as List<object>;
                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<SendEmailObject>();
                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<Type, Type> typeMappers = new Dictionary<Type, Type>();
        public static void Register<M, N>()
            where N : class, new()
        {
            if (typeMappers.ContainsKey(typeof(M)))
                throw new Exception("Key existed");

            typeMappers.Add(typeof(M), typeof(N));
        }

        public static M Resolve<M>()
        {
            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, SendEmailObject>();
IEmailService srv = Factory.Resolve<IEmailService>();
srv.Send();
srv = Factory.Resolve<IEmailService>();
srv.Send();
Console.Read();

运行输出:

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

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

时间: 2024-10-20 02:27:57

不懂设计模式的相关文章

css设计模式

(转载)原版地址:https://kb.cnblogs.com/page/551422/ 什么是设计模式? 曾有人调侃,设计模式是工程师用于跟别人显摆的,显得高大上:也曾有人这么说,不是设计模式没用,是你还没有到能懂它,会用它的时候. 先来看一下比较官方的解释:"设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码

.NET领域驱动设计—看DDD是如何运用设计模式颠覆传统架构

阅读目录: 1.开篇介绍 2.简单了解缘由(本文的前期事宜) 3.DomainModel扩展性(运用设计模式设计模型变化点) 3.1.模型扩展性 3.2.设计模式的使用(苦心专研的设计模式.设计思想可以随意使用了) 3.3.部分类的使用(封装内部对象) 3.4.高强度的OO设计(面向特定领域的高度抽象设计形成特定领域框架) 4.DomainModel业务逻辑规则配置(将扩展点分离后使用适当的配置将规则IOC进去) 5.DDD简单总结(DDD是什么?它是"战术") 1]开篇介绍 这篇文章

24种设计模式--抽象工厂模式【Abstract Factory Pattern】

女娲造人,人是造出来了,世界是热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍脑袋,忘记给人类定义性别了,那怎么办?抹掉重来,然后就把人类重新洗牌,准备重新开始制造人类. 由于先前的工作已经花费了很大的精力做为铺垫,也不想从头开始了,那先说人类(Product 产品类)怎么改吧,好,有了,给每个人类都加一个性别,然后再重新制造,这个问题解决了,那八卦炉怎么办?只有一个呀,要么生产出全都是男性,要不都是女性,那不行呀,有了,把已经有了一

【转】没那么难,谈CSS的设计模式

什么是设计模式? 曾有人调侃,设计模式是工程师用于跟别人显摆的,显得高大上:也曾有人这么说,不是设计模式没用,是你还没有到能懂它,会用它的时候. 先来看一下比较官方的解释:"设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样." 今天我们来

易学设计模式看书笔记(4) - 抽象工厂模式

 本文内容来自书上,不懂设计模式,只求混个眼熟. 三.抽象工厂模式 1.动物管理系统的例子 public interface Animal{ public void eat(); } public class Tiger implements Animal { public void eat(){ sysout.out.println("老虎会吃"); }; public void run(){ sysout.out.println("老虎会跑"); }; } pu

[转] 如何应用设计模式设计你的足球引擎(一和二)----Design Football Game(Part I and II)

原文地址: http://www.codeproject.com/KB/architecture/applyingpatterns.aspx 作者:An 'OOP' Madhusudanan 译者:赖勇浩(http://blog.csdn.net/lanphaday ) 译者说:这是一篇非常好的文章,有非常棒的例子,非常棒的文笔,非常棒的代码(VB.net编写的,但你肯定读得懂),如果你还不懂设计模式,那它肯定是最适合你的 DPs 文章之一. 第一部分 解决方案架构师:你可以尝试使用模式 愚蠢的

设计模式六大原则(1)--单一职责原则

定义: 一个类,只有一个引起它变化的原因.通俗的来说就是一个类只负责一项职责. 问题由来: 类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障. 解决方案: 遵循单一职责原则,设计两个类T1和T2,T1负责完成职责P1,T2负责完成P2.当P1变动需要修改T1时不会影响T2:同理,当P2变动需要修改T2时不会影响T1.这样,T1与T2之间职责不同,独立存在,因此无论修改哪一项的实现功能都不会影响另一方的职责. 说

深入浅出RxJava就这一篇就够了

前言: 第一次接触RxJava是在前不久,一个新Android项目的启动,在评估时选择了RxJava.RxJava是一个基于事件订阅的异步执行的一个类库.听起来有点复杂,其实是要你使用过一次,就会大概明白它是怎么回事了!为是什么一个Android项目启动会联系到RxJava呢?因为在RxJava使用起来得到广泛的认可,又是基于Java语言的.自然会有善于组织和总结的开发者联想到Android!没错,RxAndroid就这样在RxJava的基础上,针对Android开发的一个库.今天我们主要是来讲

失败的项目案例分析

题外话:印象笔记和有道云笔记的阅后感,感慨老外做出来的产品是具有一种灵性,细节中充斥着人性化:而国人做的产品比较死板(照葫芦画瓢)大致是为了完成任务而做出来的产品吧,功能点人机交互不是很流畅(仅代表个人意见). 突然联想到自己刚刚结束的一个项目中,(1)缺乏人性化设计:有一些功能点受限于开发期限的问题以及自己开发能力不足,为了实现某一功能而去完成任务,没有太多的去考虑实际使用过程中人机交互,往往缺乏人性化设计的过程.(2)面向过程编码:在开发过程中,大家都是各自完成各自的功能模块,可能会存在彼此