推荐阅读:

      在软件开发过程中,我们习惯使用new来创建对象。但是当我们创建一个实例的过程很昂贵或者很复杂,并且需要创建多个这样的类的实例时。如果仍然用new操作符去创建这样的类的实例,会导致内存中多分配一个一样的类实例对象,增加创建类的复杂度和消耗更多的内存空间。

      如果采用简单工厂模式来创建这样的系统。随着产品类增加,子类数量不断增加,会增加额外系统复杂程度,为此我们不得不引入原型模式了。

原型模式(Prototype Pattern)

      原型模式:创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

那么,我们如何用原型模型解决上面的问题呢?

      在原型模型中,因为每个类实例都是相同的,当我们需要多个相同的类实例时我们可以考虑只创建一个类实例对象,如果后面需要更多这样的实例,可以通过对原来对象拷贝一份来完成创建,这样在内存中不需要创建多个相同的类实例,从而减少内存的消耗和达到类实例的复用。

原型模式要素:

①抽象原型:声明一个克隆自身的接口;

②具体原型:该类继承了原型类,用来实现一个克隆自身的操作。

克隆操作分为:

浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制,它们只是指向同一个引用。

深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制,它们拥有不同的副本。

下面举个孙悟空复制猴子猴孙的例子来帮助大家理解原型模式:

      命名空间原型模式,包含孙悟空基类MonkeyKing,孙悟空就是原型模式中的原型对象;实现类创建猴子猴孙CreateMonkey,另外包含CloneBase泛型基类。

1创建孙悟空基类MonkeyKing


abstract class MonkeyKing
{
public abstract Prototype Clone();
}

2.创建悟空子类CreateMonkey


class CreateMonkey: MonkeyKing
{
private string monkey; //成员变量 public string monkey
{
get { return monkey; }
set { monkey= value; }
} //克隆方法
public override MonkeyKing Clone()
{
CreateMonkey monkeyKing= new CreateMonkey();
monkeyKing.monkey= monkey;
return monkeyKing;
}
}

3.使用原型模型

namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
CreateMonkey createMonkey = new CreateMonkey();
CreateMonkey copy = (CreateMonkey)createMonkey.Clone();
Console.ReadLine();
}
}
}

      上面我们简单使用原型模式来实现孙悟空克隆猴子猴孙。由于前面我们讲到从具体原型的克隆方法分为浅克隆和深克隆,下面我将继续带领大家使用C#提供的MemberwiseClone()方法和ICloneable接口来实现浅克隆和深克隆。

一.浅克隆

1.创建抽象原型WorkExperience

	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();
}
}

2.创建具体原型

	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 SetWorkExperience(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();
}
}

3.使用原型

    class Program
{
static void Main(string[] args)
{
Resume a = new Resume("马云");
a.SetPersonalInfo("男", "40");
a.SetWorkExperience("2010--2018", "X公司"); Resume b = (Resume)a.Clone();
b.SetWorkExperience("2000--2010", "XX公司"); Resume c = (Resume)a.Clone();
c.SetPersonalInfo("男", "24");
c.SetWorkExperience("1993--2000", "XXX公司"); a.Display();//xxx公司
b.Display();//xxx公司
c.Display();//xxx公司 Console.ReadKey();
}
}

二.深克隆

1.创建抽象原型WorkExperience

	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();
}
}

2.创建具体原型

	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 SetWorkExperience(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()
{
Resume obj = new Resume(this.work); 给关键字段去赋值
obj.name = this.name;
obj.sex = this.sex;
obj.age = this.age;
return obj;
}
}

3.使用原型

   class Program
{
static void Main(string[] args)
{
Resume a = new Resume("靖凡");
a.SetPersonalInfo("男", "29");
a.SetWorkExperience("2010--2018", "X公司"); Resume b = (Resume)a.Clone();
b.SetWorkExperience("2000--2010", "XX公司"); Resume c = (Resume)a.Clone();
c.SetPersonalInfo("男", "24");
c.SetWorkExperience("1993--2000", "XXX公司"); a.Display();//x公司
b.Display();//xx公司
c.Display();//xxx公司 Console.ReadKey();
}
}

      通过上面三个例子,如果你对原型模式有了更好的理解,麻烦文末点个赞,如果你有什么疑惑,也欢迎评论区留言!!!

设计模式(C#)——04原型模式的更多相关文章

  1. java23种设计模式——四、原型模式

    源码在我的github和gitee中获取 目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式- ...

  2. Net设计模式实例之原型模式( Prototype Pattern)

    一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...

  3. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

  4. 设计模式学习心得<原型模式 Prototype >

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式是实现了一个原型接口,该接口用于创建当 ...

  5. IOS设计模式浅析之原型模式(Prototype)

    原型模式的定义 “使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象”.最初的定义出现于<设计模式>(Addison-Wesley,1994). 简单来理解就是根据这个原型创建 ...

  6. 大话设计模式Python实现-原型模式

    原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 一个原型模式的简单demo: #!/usr/bin/env python # -*- c ...

  7. 重学 Java 设计模式:实战原型模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老板你加钱我的代码能飞 程序员这份工作里有两种人:一类是热爱喜欢的.一类是仅当成工作 ...

  8. 深度分析:java设计模式中的原型模式,看完就没有说不懂的

    前言 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的 ...

  9. 设计模式系列之原型模式(Prototype Pattern)——对象的克隆

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

随机推荐

  1. c++ 动态规划(数塔)

    c++ 动态规划(dp) 题目描述 观察下面的数塔.写一个程序查找从最高点到底部任意位置结束的路径,使路径经过数字的和最大. 每一步可以从当前点走到左下角的点,也可以到达右下角的点. 输入 5 13 ...

  2. FAIRR

    FAIRR 在进行一项工作时需要注意学习.应用和改进已有信息和成果,可参考FAIRR原则: Find existing info and result, Add to and Improve it, ...

  3. jmter快速安装

    一.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具,用于接口和压力测试,所以前提是一定更要安装jdk. 二.下载安装 下载:官网下载 下载完成后运行包里的jmete ...

  4. 小白学python-day04-运算符、while循环相关

    今天是day04.以下是学习总结. 但行努力,莫问前程. ----------------------------------------------------------------------- ...

  5. HashTable源码解读

    一:总述 底层实现原理是用数组+链表,与HashMap一样,但HashTable是线程安全的,HashMap是非线程安全的 下面是其结构图(与hashMap类似) 二:属性说明 /** * The h ...

  6. ajax性能优化

    ajax性能优化 例: 模块: A B C D 开销: 50%  3% 25%   22% 如果我们优化B就如同那些那些只执行一次的代码,性能·提高不到哪里去:反之,我们去优化A,比如去优化它的循环, ...

  7. 史上最强Java开发环境搭建

    在项目产品开发中,开发环境搭建是软件开发的首要阶段,也是必须阶段,只有开发环境搭建好了,方可进行开发,良好的开发环境搭建,为后续的开发工作带来极大便利. 对于大公司来说,软件开发环境搭建工作一般是由运 ...

  8. Web项目如何做单元测试

    你可能会用单元测试框架,python的unittest.pytest,Java的Junit.testNG等. 那么你会做单元测试么!当然了,这有什么难的? test_demo.py def inc(x ...

  9. java并发编程(二十五)----(JUC集合)LinkedBlockingDeque和ConcurrentLinkedDeque介绍

    Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque.这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂. LinkedBlockingDeque 我们 ...

  10. javaweb基础整理随笔-----上传与下载步骤详解

    这次整理的是上传与下载的原生代码解析: 上传:1.对页面的要求:enctype="multipart/form-data" method="post"      ...