当前位置:   article > 正文

C#设计模式之:原型模式_c# 原型模式

c# 原型模式

原型模式(Prototype)

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

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

UML
这里写图片描述

代码

abstract class Prototype
{
    private string id;

    public Prototype(string id)
    {
        this.Id = id;
    }

    public string Id { get => id; set => id = value; }

    public abstract Prototype Clone();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
class ConcretePrototype1 : Prototype
{
    public ConcretePrototype1(string id) : base(id)
    {

    }

    public override Prototype Clone()
    {
        return (Prototype)this.MemberwiseClone();//浅拷贝
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
// test
ConcretePrototype1 p1 = new ConcretePrototype1("I");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Cloned: {0}", c1.Id);
  • 1
  • 2
  • 3
  • 4
// result
Cloned: I
  • 1
  • 2

从用户层次来看,不用实例化ConcreteProtype1,直接克隆就行了

一般在初始化的信息不发生变化的情况下,克隆是最好的办法,这即隐藏了对象创建的细节,又对性能是大大的提高。它等于不用重新初始化对象,而是动态地获得对象运行时的状态。

.NetSystem命名空间中提供了ICloneable接口,其中有一个唯一的方法Clone( ),你只要实现这个接口就可以完成原型模式

MemberwiseClone( ) 方法:如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其复本引用同一对象。

使用浅拷贝的样例

class WorkExperience
{
    private string workDate;
    private string company;

    public string WorkDate { get => workDate; set => workDate = value; }
    public string Company { get => company; set => company = value; }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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();
    }

    public void SetPersonalInfo(string sex, string age)
    {
        this.sex = sex;
        this.age = age;
    }

    public void SetWordExperience(string timeDate, string company)
    {
        work.WorkDate = timeDate;
        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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
// test
Resume a = new Resume("大鸟");
a.SetPersonalInfo("男", "29");
a.SetWordExperience("2001-2008", "XX 公司");

Resume b = (Resume)a.Clone();
b.SetWordExperience("1998-2006", "YY 公司");

Resume c = (Resume)a.Clone();
c.SetWordExperience("1998-2018", "ZZ 公司");

a.Display();
b.Display();
c.Display();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
// result
大鸟 男 29
工作经历:1998-2018 ZZ 公司
大鸟 男 29
工作经历:1998-2018 ZZ 公司
大鸟 男 29
工作经历:1998-2018 ZZ 公司
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其它对象的引用都仍然指向原来的对象
深拷贝:把引用对象的变量指向复制过来的新对象,而不是原来的被引用的对象

深拷贝实现

class WorkExperience : ICloneable
{
    private string workDate;
    private string company;

    public string WorkDate { get => workDate; set => workDate = value; }
    public string Company { get => company; set => company = value; }

    public object Clone()
    {
        return (Object)this.MemberwiseClone();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
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();
    }

    private Resume(WorkExperience work)
    {
        this.work = (WorkExperience)work.Clone();
    }

    public void SetPersonalInfo(string sex, string age)
    {
        this.sex = sex;
        this.age = age;
    }

    public void SetWordExperience(string timeDate, string company)
    {
        work.WorkDate = timeDate;
        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()
    {
        Resume obj = new Resume(this.work); // 关键点
        obj.name = this.name;
        obj.sex = this.sex;
        obj.age = this.age;

        return obj;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
// test 上同
// result
大鸟 男 29
工作经历:2001-2008 XX 公司
大鸟 男 29
工作经历:1998-2006 YY 公司
大鸟 男 29
工作经历:1998-2018 ZZ 公司
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/487358
推荐阅读
相关标签
  

闽ICP备14008679号