设计模式:原型模式

来源:互联网 发布:淘宝搭配套餐 编辑:程序博客网 时间:2024/06/05 18:52

1.引言

原型模式是一种“另类”的创建模式,创建新对象(也称为克隆模式)的工厂就是原型类自身,工厂方法由负责复制原型对象的克隆方法来实现。

2.原型模式的结构

原型模式
(1)Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口
(2)ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法返回一个克隆对象。
(3)Client(客户类):在客户类中,让一个原型对象克隆自身从而创建一个新的对象,只需要直接实例化或者通过工厂方法等方式创建一个原型对象,再通过调用该对象的克隆方法即可得到多个相同的对象。

3.浅克隆与深克隆的区别

根据在复制原型对象的同时是否复制包含在原型对象中引用类型的成员变量,原型模式的克隆机制分为两种:浅客隆和深克隆(1)浅克隆在浅克隆中,如果原型对象的成员变量是值类型,将复制一份克隆给对象,如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象都指向相同的内存地址。(2)深克隆在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。

这里写图片描述

4.原型模式的实现

通用的克隆实现方法
    public abstract class Prototype    {        public abstract Prototype Clone();    }    public class ConcreatePrototype:Prototype    {        private string attr;        public string Attr        {            get { return attr; }            set { attr = value; }        }        //克隆方法        public override Prototype Clone()        {            ConcreatePrototype prototype = new ConcreatePrototype();            prototype.Attr = attr;            return prototype;        }    }
    class Program    {        static void Main(string[] args)        {            ConcreatePrototype prototype = new ConcreatePrototype();            prototype.Attr = "abc";            ConcreatePrototype copy = (ConcreatePrototype)prototype.Clone();            Console.WriteLine(copy.Attr);//abc            Console.ReadKey();        }    }
浅克隆的实现
    public class Member    {        private string test;        public string Test        {            get { return test; }            set { test = value; }        }        public void TestFun()        {        }    }    public class ConcretePrototypeA    {        private Member member;        public Member Member        {            get { return member; }            set { member = value; }        }        //浅克隆        public ConcretePrototypeA Clone()        {            return (ConcretePrototypeA)this.MemberwiseClone();        }    }
    class Program    {        static void Main(string[] args)        {            ConcretePrototypeA prototype = new ConcretePrototypeA();            prototype.Member = new Member() { Test = "abc" };            ConcretePrototypeA copy = prototype.Clone();            Console.WriteLine(prototype == copy);//false            Console.WriteLine(prototype.Member == copy.Member);//true,表示浅客隆            Console.ReadKey();        }    }
使用ICloneable接口充当了抽象原型类的角色,深度克隆的实现
    public class Member    {        private string test;        public string Test        {            get { return test; }            set { test = value; }        }        public void TestFun()        {        }    }    class ConcretePrototypeB:ICloneable    {        private Member member;        public Member Member        {            get { return this.member; }            set { this.member = value; }        }        public object Clone()        {            ConcretePrototypeB copy = (ConcretePrototypeB)this.MemberwiseClone();            Member newMember = new Member();            copy.Member = new Member() { Test = "abc" };            return copy;        }    }
    class Program    {        static void Main(string[] args)        {            ConcretePrototypeB prototype = new ConcretePrototypeB();            prototype.Member = new Member() { Test = "abc" };            ConcretePrototypeB copy = prototype.Clone() as ConcretePrototypeB;            Console.WriteLine(prototype == copy);//false            Console.WriteLine(prototype.Member == copy.Member);//false,表示深客隆            Console.ReadKey();        }    }

5.结束

一般情况下使用ICloneable充当抽象原型类的角色,在实现ICloneable接口时,通常提供的除MemberwiseClone()以外的深克隆方法。除了通过直接创建新的成员对象来手工实现深克隆外,还可以通过反射、序列化等方式来实现深克隆,注意在使用序列化实现时要求所有被引用的对象都必须是可序列化的。
0 0