zoukankan      html  css  js  c++  java
  • 大话设计模式之原型模式

      原型模式

     定义:

     用原型实例制定创建对象的种类,并通过拷贝这些原型。创建新的对象。

     实质:

     就是从一个对象在创建还有一个可定制的对象。并且不须要知道不论什么创建的细节。

     核心:

    (1)、实现Cloneable接口,能够使用此接口的类上使用clone方法。

    (2)、重写Object类中的clone方法,由于全部类的父类是Object类。Object有一个clone方法。作用是返回对象的一个拷贝。可是其作用域protected类型的,一般的类无法调用,因此,将clone改为public类型。

     结构图:

     

     代码实现:

     

        class Resume : ICloneable//实现ICloneable接口
        {
            private string name;
            private string computer;
            public Resume(string name)
            {
                this.name = name;
            }
            public void SetWordExperience(string computer)
            {
                this.computer = computer;
            }
            public void Display()
            {
                Console.WriteLine("{0}", name);
                Console.WriteLine("工作经历: {0}", computer);
            }
            public Object Clone()//重写Clone方法,改为public类型
            {
                return (Object)this.MemberwiseClone();
            }
        }

      client代码:

        class Program
        {
            static void Main(string[] args)
            {
                Resume a = new Resume("大鸟");
                a.SetWordExperience("XX大公司");
                a.Display();
    
                for (int i = 0; i < 3; i++)//没有别的意思,仅仅是用用
                {
                    Resume _i = (Resume)a.Clone();
                    _i.SetWordExperience("YY大公司");
                    _i.Display();
                }
                Console.Read();
            }
        }

      这就是简单复制。一般在初始化的信息不发生变化的情况下,科隆市最好的办法,这既隐藏了对象创建的细节,有对性能是大大的提高。

     使用原型模式创建对象比直接new一个对象在性能上要好的多。由于Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的区别很明显。

     Object类的clone方法仅仅会拷贝对象中的主要的数据类型。对于数组、容器对象、引用对象等都不会拷贝。这就是浅拷贝。假设要实现深拷贝。必须将原型模式中的数组、容器对象、引用对象等另行拷贝。

     浅复制和深复制

     这里指谈谈引用对象的深复制:

     须要解决的代码:

        class WrokExperience//新增加一个类
        {
            private string workDate;
            public string WorkDate
            {
                get { return workDate; }
                set { workDate = value; }
            }
        }
        class Resume : ICloneable
        {
            private string name;
            private string computer;
            private WrokExperience work;//引用类
            public Resume(string name)
            {
                this.name = name;
                work = new WrokExperience();
            }
            public void SetWorkExperience(string computer, string workDate)
            {
                this.computer = computer;
                work.WorkDate = workDate;
            }
            public void Display()
            {
                Console.WriteLine("{0}", name);
                Console.WriteLine("工作经历: {0} {1}", work.WorkDate, computer);//这里的WorkDate ,须要的是每一次赋值的。

    } public object Clone() { return (Object)this.MemberwiseClone(); } } class Program { static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetWorkExperience("1998-2008", "XX大公司"); Resume _i = (Resume)a.Clone(); _i.SetWorkExperience("1997-2008", "YY大公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1996-2008", "ZZ大公司"); a.Display(); _i.Display(); b.Display(); Console.Read(); } }


      执行结果:


     而实际上,我们须要的是不一样的。

     改动代码:

        class WorkExperience : ICloneable//对于引用类相同的拷贝
        {
            private string workDate;
            public string WorkDate
            {
                get { return workDate; }
                set { workDate = value; }
            }
            public Object Clone()
            {
                return (Object)this.MemberwiseClone();
            }
        }
        class Resume : ICloneable
        {
            private WorkExperience work;
            private string name;
            private string computer;
            public Resume(string name)
            {
                this.name = name;
                work = new WorkExperience();
            }
            private Resume(WorkExperience work)//做了一个私有的构造方法。让它克隆完毕,然后再给这个”简历“对象的响应字段赋值,终于返回一个深复制的简历对象
            {
                this.work = (WorkExperience)work.Clone();
            }
            public void SetExperience(string workDate, string computer)
            {
                work.WorkDate = workDate;
                this.computer = computer;
            }
            public void Display()
            {
                Console.WriteLine("{0}", name);
                Console.WriteLine("工作经历: {0} {1}", work.WorkDate, computer);
            }
            public Object Clone()
            {
                Resume obj = new Resume(this.work);
                obj.name = this.name;
                obj.computer = computer;
                return obj;
            }
        }

      client代码不变。

     执行结果:


     得到预期结果。

     事实上,我们使用原型模式,简单的说我们就是简化对象的创建。

     

  • 相关阅读:
    【漏洞挖掘】攻击对外开放的Docker API接口
    使用密钥认证机制远程登录Linux
    极客时间-左耳听风-程序员攻略开篇-零基础启蒙
    WEBSHELL恶意代码批量提取清除工具
    string替换字符串,路径的斜杠替换为下划线
    Linux下文件的三个时间意义及用法
    记录一次lnmp故障报告
    Centos 7.2编译安装MariaDB-10.0.xx
    win 7 浏览器被篡改小插曲
    【 sysbench 性能基准测试 】
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6791632.html
Copyright © 2011-2022 走看看