zoukankan      html  css  js  c++  java
  • 设计模式学习笔记原型模式

    概述:                                                                                                       

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

    实用场合:                                                                                                 

    1.当一个系统应该独立于它的产品创建、构成和表示时。

    2、当要实例化的类是在运行时刻指定时,例如通过动态装载。

    3、为了避免创建一个与产品类层次平行的工厂类层次时。

    4、当一个类的实例只能有几个不同状态组合中的一种时。

    类图:                                                                                                      

    1.定义一个抽象类,声明克隆自身的接口

        /// <summary>
    /// 抽象原型类,声明一个克隆自身的接口
    /// </summary>
    abstract class Prototype
    {
    private string id;
    public Prototype(string id)
    {
    this.id = id;
    }
    public string Id { get { return id; } }
    /// <summary>
    /// 关键的克隆接口
    /// </summary>
    /// <returns></returns>
    public abstract Prototype Clone();
    }

    2.具体的原型类,实现接口

        /// <summary>
    /// 具体原型类,实现一个克隆自身的操作
    /// </summary>
    class ConcretePrototype : Prototype
    {
    /// <summary>
    /// 调用基类的构造函数
    /// </summary>
    /// <param name="id"></param>
    public ConcretePrototype(string id) : base(id) { }

    public override Prototype Clone()
    {
    //创建当前对象的浅表副本,方法是创建一个新的对象,然后将当前对象的非静态字段复制到该对象
    //如果字段是值类型,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象
    //因此,原始对象及其副本引用同一对象。
    return (Prototype)this.MemberwiseClone();
    }
    }

      3.客户端调用

            /// <summary>
    /// 测试原型方法
    /// </summary>
    static void TestPrototype()
    {
    ConcretePrototype p1
    = new ConcretePrototype1("I");
    //克隆p1就能得到新的实例c1
    ConcretePrototype c1 = (ConcretePrototype)p1.Clone();

    Console.WriteLine(
    "Cloned:{0}",c1.Id);

    Console.Read();
    }

    补充:                                                                                                       

    实际上.net framework已经提供了ICloneable接口,只要实现这个接口就可以完成原型了,上面的原始代码只实现了浅表复制,对于深复制看下面两个例子的不同之处就可以了。

    举例说明:                                                                                                 

    这里用大话设计模式里的例子

    浅表复制

    View Code
     class Resume : ICloneable
    {
    private string name;
    private string sex;
    private string age;
    private string timeArea;
    private string company;

    public Resume(string name)
    {
    this.name = name;
    }
    /// <summary>
    /// 设置个人信息
    /// </summary>
    /// <param name="sex"></param>
    /// <param name="age"></param>
    public void SetPersonalInfo(string sex,string age)
    {
    this.age = age;
    this.sex = sex;
    }
    public void SetWorkExperience(string timeArea,string company)
    {
    this.timeArea = timeArea;
    this.company = company;
    }
    public void Display()
    {
    Console.WriteLine(
    "{0} {1} {2}",name,age,sex);
    Console.WriteLine(
    "工作经历:{0} {1}",timeArea,company);
    }
    public Object Clone()
    {
    return (Object)this.MemberwiseClone();
    }
    }
    //客户端调用
    /// <summary>
    /// 测试简原型历类
    /// </summary>
    static void TestPrototypeResume()
    {
    Resume a
    = new Resume("小鸟");
    a.SetPersonalInfo(
    "","25");
    a.SetWorkExperience(
    "2007-2008","xx科技");

    Resume b
    = (Resume)a.Clone();
    b.SetWorkExperience(
    "2008-2009","xxx文化");

    Resume c
    = (Resume)a.Clone();
    c.SetPersonalInfo(
    "","26");

    a.Display();
    b.Display();
    c.Display();
    Console.Read();

    }

    深复制:就是将引用类型里的值也一并复制了,二不仅仅是复制引用类型对象本身,客户端调用同浅表复制

    View Code
        /// <summary>
    /// 深表制
    /// </summary>
    class WorkExperience : 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 Resume2 : ICloneable
    {
    private string name;
    private string sex;
    private string age;
    private WorkExperience work;
    public Resume2(string name)
    {
    this.name = name;
    work
    = new WorkExperience();
    }
    /// <summary>
    /// 提供Clone方法调用的私有构造函数,克隆工作经历的数据
    /// </summary>
    /// <param name="work"></param>
    private Resume2(WorkExperience work)
    {
    this.work = (WorkExperience)work.Clone();
    }

    /// <summary>
    /// 设置个人信息
    /// </summary>
    /// <param name="sex"></param>
    /// <param name="age"></param>
    public void SetPersonalInfo(string sex, string age)
    {
    this.age = age;
    this.sex = sex;
    }
    //设置工作经历
    public void SetWorkExperience(string workDate, string company)
    {
    work.WorkDate
    = workDate;
    work.Company
    = company;
    }
    public void Display()
    {
    Console.WriteLine(
    "{0} {1} {2}", name, age, sex);
    Console.WriteLine(
    "工作经历:{0} {1}", work.WorkDate, work.Company);
    }
    public Object Clone()
    {
    //关键部分:调用私有的构造方法,让工作经历克隆完成,然后给这个简历的相关字段赋值,最终返回一个深复制的对象
    Resume2 obj = new Resume2(this.work);
    obj.name
    = this.name;
    obj.sex
    = this.sex;
    obj.age
    = this.age;
    return obj;

    }
    }

    小结:                                                                                                        

    原型模式有意思吧

  • 相关阅读:
    LeetCode 123. Best Time to Buy and Sell Stock III (stock problem)
    精帖转载(关于stock problem)
    LeetCode 122. Best Time to Buy and Sell Stock II (stock problem)
    LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
    LeetCode 120. Triangle
    基于docker 搭建Elasticsearch5.6.4 分布式集群
    从零开始构建一个centos+jdk7+tomcat7的docker镜像文件
    Harbor实现容器镜像仓库的管理和运维
    docker中制作自己的JDK+tomcat镜像
    docker镜像制作---jdk7+tomcat7基础镜像
  • 原文地址:https://www.cnblogs.com/jqbird/p/2145417.html
Copyright © 2011-2022 走看看