一、定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
通俗点来讲就是克隆指定的对象
原型模式其实就是从一个对象再创建另一个可定制的对象,而且不需要知道任何创建的细节。
Prototype:为克隆对象提供一个克隆接口
ConcretePrototype:实现克隆接口来完成克隆自身的操作
二、特点
原型模式中的拷贝对象分为:浅复制和深复制
浅复制:
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其它对象的引用都仍指向原来的对象
简单来说:对于引用类型来说克隆的对象如果修改了相关的属性,是无法显示出来的,这样克隆出来的对象始终与原对象相同。
深复制:
把引用对象的变量指向复制郭的新对象,而不是原有的被引用的对象
对引用类型来说,对克隆对象进行修改显示结果为不同的对象。
三、优缺点
优点:
1.提高了运行效率,不用去实例化类
缺点:
1.实现复杂,重写clone方法
四、什么时候使用
当系统需要大量创建相同或相似的对象时。
五、实例
1.原型模式
原型类
abstract class Prototype
{
private string id;
// Constructor public Prototype(string id) { this.id = id; } // Property public string Id { get { return id; } } public abstract Prototype Clone();//Clone方法 }
具体原型类
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id)
: base(id)
{
}
public override Prototype Clone() { // Shallow copy return (Prototype)this.MemberwiseClone();//创建当前对象的浅表副本 } }
客户端代码
static void Main(string[] args)
{
ConcretePrototype1 p1 = new ConcretePrototype1(“I”);
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();//得到新的实例C1
Console.WriteLine(“Cloned: {0}”, c1.Id);
}
2.简历的深复制实现
工作经历类
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(); } private Resume (WorkExperience work) //提供Clone 方法调用的私有构造函数,以便克隆“工作经历”的数据 { 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;
客户端
static void Main(string[] args)
{
Resume a = new Resume(“大鸟”);
a.SetPersonalInfo(“男”, “29”);
a.SetWorkExperience(“1998-2000”, “XX公司”);
Resume b = (Resume)a.Clone(); b.SetWorkExperience("1998-2006", "YY企业"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("男", "24"); c.SetWorkExperience("1998-2003", "ZZ企业"); a.Display(); b.Display(); c.Display(); Console.Read(); }
六、设计知识点
1.构造方法
1.对类进行初始化
2.构造方法与类同名,无返回值
3.不需要void,在new的时候调用
2.访问修饰符
1.private:私有的,只允许同一个类中的成员访问,其他类或子类无法访问
2.public:公有的,它所修饰的类的成员可以允许其他任何类访问
3.protected:保护的,只有子类可以访问
4.internal:内部的,类默认的就是,表示同一个项目中的代码可以访问
3.关系
组合:整体和个体之间的关系,整体和个体密不可分,不可分割
图形:实心菱形+实线箭头
实现:个体的实例化在整体的构造函数中
4.抽象类
abstract关键字
抽象类表示一个抽象概念,它提供一个继承的出发点,当设计一个新的抽象类时,一定是用来继承的,在一个以继承关系形成的等级结构中,树叶节点应当时具体类,树枝节点均应当时抽象类。
注意:
1.抽象类不能实例化
2.抽象方法必须被子类重写
3.如果类中包含抽象方法,那么类就必须定义为抽象类
5.接口
是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。
一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。