创建型模式之原型模式和单例模式

来源:互联网 发布:淘宝店铺年销售额查询 编辑:程序博客网 时间:2024/05/15 02:51

      创建型模式除了三大工厂和建造者模式,就剩下这两个了,原型模式和单例模式。下面就谈谈这两个模式。

一、原型模式

定义

原型模式(prototype):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

自己的理解:说白了就是复制。就像简历的例子一样,我们肯定是需要好多份简历不能每次都执行一遍程序,所以肯定得把制作简历抽象出一个类,用的时候实例化就OK了嘛,但是,如果需要1000份就非要实例化1000次吗?太浪费资源空间了吧,所以就用了一个非常洋气的方法叫clone。clone其实就是复制嘛,但是不能老克隆一模一样的吧,我想给别人也写个简历呢,所以就涉及到深复制和浅复制了。

UML类图



代码示例(简历)

namespace 原型模式{    class Program    {        static void Main(string[] args)        {            Resume a = new Resume("大鸟");            a.SetPersonalInfo("男","29");            a.SetWorkExperience("1998-2000","xx公司");            Resume b = (Resume)a.Clone();            b.setPersonalInfo("女","55");            b.SetWorkExperinece("2000-3000","yy企业");            a.Display();            b.Display();            Console.Read();        }    }    #region 简历 深复制和浅复制    //工作经历    //class WorkExperience       class WorkExperience:ICloneable  //工作经历实现ICloneable 接口  深复制 实现接口    {        private string workDate;        public string WorkDate        {            get { return workDate; }            set { workDate = value; }        }        private string company;        public string Company        {            get { return company; }            set { company = value; }        }          //深复制          public Object Clone()        {            return (Object)this.MemberwiseClone();        }    }    //简历    class Resume : ICloneable    {        private string name;        private string sex;        private string age;        private WorkExperience work; //引用工作经历对象        public Resume(string name)        {            this.name = name;            work = new WorkExperience();// 在“简历类”实例化的同时实例化“工作经历”        }        //提供clone方法调用的私有构造函数,以便克隆工作经历的数据        private Resume(WorkExperience work)        {            this.work = (WorkExperience)work.<span style="color:#3366ff;">Clone()</span>;        }        //设置个人信息        public void SetPersonalInfo(string sex, string age)        {            this.sex = sex;            this.age = age;        }        //设置工作经历        public void SetWorkExperinece(string workDate, string company)        {            work.WorkDate = workDate;//调用此方法是,给对象的两属性赋值            work.Company = company;        }        //显示        public void Display()        {            Console.WriteLine("{0} {1} {2}",name,sex,age );            Console.WriteLine("工作经历:{0} {1}",work.WorkDate,work.Company);        }        public Object Clone()        {            //return (Object)this.MemberwiseClone();  浅复制            //调用私有的构造方法,让工作经历克隆完成,然后再给这个简历对象的相关字段赋值,最终返回一个深复制的简历对象            Resume obj = new Resume(this.work);            obj.name = this.name;            obj.sex = this.sex;            obj.age = this.age;            return obj;        }        internal void setPersonalInfo(string p1, string p2)        {            throw new NotImplementedException();        }        internal void SetWorkExperience(string p1, string p2)        {            throw new NotImplementedException();        }    }    #endregion}

适用场景

    初始化信息不发生变化的情况下,需要重复的创建对象。优点是隐藏对象创建细节,大大提高性能。

深复制和浅复制

浅复制:如果字段是值类型的,则对该字段进行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原始对象及其副本引用同一对象。

深复制:是将指向内容复制到给当前对象新分配的缓冲区中的一种复制方式,把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象都复制一遍。

自己的理解:
  A引用B,现在要复制A(二者区别针对引用类型)
  浅复制: A1引用B
  深复制: A1引用B1
 浅复制不复制引用的对象,之前引用的谁,现在还引用谁
 深复制会开辟空间把引用对象也复制过来

二、单例模式

    单例模式是设计模式中最简单的模式之一。根本就没有涉及到其他复杂的类,就是在原来的类上加上双重锁或设置静态初始化使得这个类自己控制自己只能有一个实例。

定义

    单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。

必要性

    对于某些类来说,只有一个实例是很重要的。遇到多线程问题的时候,只能让一个线程工作,其他的等待。比如我们在打印的时候,可能一下选择了好几个打印任务,但是只能有一个正在工作的任务。在创建窗体的时候,如果不对创建窗体的唯一性进行控制,就可以创建多个相同的窗体,重复的对象是对内存资源的一种浪费。

代码示例(创建窗体)
amespace 单例模式{        #region<span style="color:#ff0000;"> 懒汉模式 双重锁定</span>    class Singleton    {        private static Singleton instance;//抽出来成为全局变量        private static readonly object syncRoot = new object();//程序运行时创建一个静态只读的进程辅助对象        private Singleton()  //构造方法用private,阻止外界new此类创建实例        { }        public static Singleton GetINstance()//此方法是获得本类实例的唯一全局访问点        {            if (instance == null)// 没有创建实例,有两个进程等着,只能进去一个            {                lock(syncRoot )                {                    if(instance == null)//保证如果有一个实例创建了,另一个就无法创建                    {                        instance = new Singleton();                    }                }            }            return instance;        }    }    #endregion    #region <span style="color:#ff0000;">饿汉式单例类</span>    //封装的,阻止发生派生    public sealed class Singleton    {        <span style="color:#ff0000;">//静态初始化是在类被加载的时候就将它实例化        private static readonly Singleton instance = new Singleton();</span>        private Singleton() { }        public static Singleton GetInstance()        {            return instance;        }    }    #endregion}

如何实现单例

第一步:全局访问
        把类变量声明成全局变量,不要在某一事件中声明,这样可以判断类是否被实例化过。
第二步:实例化控制
  方法一:双重锁定
  这针对的是多线程问题。
if (instance == null)// 没有创建实例,有两个进程等着,只能进去一个            {                lock(syncRoot )                {                    if(instance == null)//保证如果有一个实例创建了,另一个就无法创建
第一个if是判断是否已经创建过实例,如果没有,上把锁,只能进去一个线程。第二个if是判断第一线程有没有创建实例,如果创建了第二个线程就不能再创建。
   由于该类是在第一次被引用的时候,才会将自己实例化,所以被称为懒汉式单例类。
   方法二:静态实例化
   这种方法不需要开发人员显示的编写线程安全代码,即可解决多线程环境下不安全的问题。这种静态初始化的方式是在自己被加载时就将自己实例化,所以被称为饿汉式单例类。

总结

    在实际开发过程中肯定会有好多涉及到多线程的问题,所以单例模式也要掌握熟练。单例模式主要就是解决多线程的安全问题。如果开发过程中遇到只需要一个实例的问题就考虑考虑单例模式,如果对一个类重复调用,内容没有多大改变,跟复制似的就考虑原型模式。
    
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 剑与家园魔镜带错兵怎么办 橙子vr上下反了怎么办 我的恐龙手机不支持ar怎么办 被小人陷害又无计可施怎么办 蚂蚁借呗2万逾期怎么办 蚂蚁借呗还款金额受限怎么办 蚂蚁借呗不能借钱了怎么办 美柚手机号换了怎么办 美柚他他圈被禁言了怎么办? 被蝎子蜇了屁股怎么办 被蝎子蛰了该怎么办 孕妇让蝎子蛰了怎么办 脸被蝎子蛰了怎么办 皮肤看着有点老怎么办 王者铭文被卖了怎么办 游戏cp送我皮肤怎么办 消防改革武警学院的学员怎么办 几把毛掉的厉害怎么办 从公务员调入事业单位的怎么办 电车被城管扣了怎么办 超变战陀发射器绳坏了怎么办 家里人总打击我怎么办干啥都要骂 欧陆风云4破产后怎么办 车被别人喷了漆怎么办 龙分期绑银行卡维护钱还不上怎么办 去维和要是伤了怎么办 头盔镜片刮花了怎么办 小牛u1钥匙丢了怎么办 非牛顿流体干了怎么办 刺激战场0信誉分怎么办 假如非牛顿干了怎么办? 退出id后照片了怎么办 小麦收割机麦糠有籽粒怎么办 在家带娃没钱花怎么办 看3d电影近视的怎么办 摩托车电瓶没电了怎么办 踏板摩托车电瓶没电了怎么办 摩托车离合油没了怎么办 论文数据计算错误该怎么办 脚被擦破皮了痛怎么办 脚撞到了很疼怎么办