原型(Prototype)模式

21 篇文章 0 订阅
18 篇文章 3 订阅

原型(Prototype)模式:创建型模式

    使用原型实例指定创建对象的种类,然后通过拷贝这些原型实例来创建新的对象。


动机    

    在软件系统中,经常面临着“某些结构复杂的对象”的创建工用;由于需求变化,这些对象经常
面临着剧烈变化,但是它们却拥有比较稳定一致的接口。

    如何应对这种变化?如何向客户端程序隔离出这些易变对象,从而使得依赖这些易变对象的客户
端程序不随着需求改变而改变?

 

要点 

    Prototype模型同样用于隔离对象的使用者和具体类之间的紧耦合关系,它同样要求这些易变类
拥有稳定的接口。Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法
来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象--所需工作仅仅是注
册一个新类的对象(即原型),然后在任何需要的地方不断的克隆即可。

     Prototype模式中的Clone方法可以利用.net中的Object类的MemberwiseClone()方法、序列化
(使用BinaryFormatter类,需在序列化的目标类上加【Seriallize】特性)或反射的方法来实
现,MemberwiseClone()方法为浅拷贝,即值类型成员的数据值直接拷贝到新对象中,两对象互
不影响,但引用类型的成员只是拷贝引用,不拷贝指向的对象,新旧对象的该类成员仍然指向相
同的对象,这样就会相互影响;序列化(BianrySeriallize,需在在类上加【Seriallize】特性
)或反射的方法则可以避免以上问题,被称为深拷贝。

代码示例:

一般实现,紧耦合,依赖具体类型,不利于扩展,违反开闭原则。

    //实现ICloneable接口
    class MP3Palyer:ICloneable
    {
        /// <summary>
        /// 当前播放进度
        /// </summary>
        public int CurPlayProcessValue { get; set; }

        /// <summary>
        /// 当前歌典名称
        /// </summary>
        public string CurSingName { get; set; }

        
        public string[] SingsList = new string[10];

        public object Clone()
        {
            //使用object类的克隆方法,浅拷贝
            return this.MemberwiseClone();
        }
    }

调用:

        /// <summary>
        /// 在调用者内部使用new来创建对象,紧耦合,依赖具体类型
        /// </summary>
        static void CreatePlayer()
        {
            //建立1000个播放器,使用new方式
            MP3Palyer pp = new MP3Palyer();

            for (int i = 0; i < 100000; i++)
            {
                //效率低下
                //MP3Palyer pc = new MP3Palyer();

                //类的实现了ICloneable接口,效率比new的方式高
                MP3Palyer pc = (MP3Palyer)pp.Clone();
            }
        }

       

        /// <summary>
        /// 在调用者内部使用传入实例的来创建(Clone方法)新对象,紧耦合,依赖具体类型
        /// </summary>
        /// <param name="player"></param>
        static void CreatePlayer(MP3Palyer player)
        {
            //创建1000个播放器实例
            for (int i = 0; i < 100000; i++)
            {

                //类的实现了ICloneable接口,效率比new的方式高
                MP3Palyer pc = (MP3Palyer)player.Clone();
            }
        }

原型模式实现,松耦合,不依赖具体类型,利于扩展,符合开闭原则。

//抽象接口
abstract class IPlayer : ICloneable
    {
        public abstract object Clone();
    }

    /// <summary>
    /// 实现Player接口
    /// </summary>
    class MP3Palyer : IPlayer
    {
        /// <summary>
        /// 当前播放进度
        /// </summary>
        public int CurPlayProcessValue { get; set; }

        /// <summary>
        /// 当前歌典名称
        /// </summary>
        public string CurSingName { get; set; }

        public string[] SingsList = new string[10];

        /// <summary>
        /// 克隆,浅拷贝
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            //使用object类的克隆方法,浅拷贝
            return this.MemberwiseClone();
        }


    }

    /// <summary>
    /// 实现Player接口
    /// </summary>
    class MP4Palyer : IPlayer
    {
        /// <summary>
        /// 当前播放进度
        /// </summary>
        public int CurPlayProcessValue { get; set; }

        /// <summary>
        /// 当前歌典名称
        /// </summary>
        public string CurSingName { get; set; }

        public string[] SingsList = new string[10];

        /// <summary>
        /// 克隆,浅拷贝
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            //使用object类的克隆方法,浅拷贝
            return this.MemberwiseClone();
        }
    }

调用:

        /// <summary>
        /// 在调用者内部使用传入实例的来创建(Clone方法)新对象,松耦合,依赖接口
        /// </summary>
        /// <param name="player"></param>
        static void CreatePlayer(IPlayer player)
        {

            for (int i = 0; i < 100000; i++)
            {
                IPlayer pc = (IPlayer)player.Clone();
            }
        }


       static void Main()
       {
          CreatePlayer(new MP3Palyer());

          CreatePlayer(new MP4Palyer());
       }

深拷贝与浅拷贝的介绍请参考此处.

创建型设计模式总结

    单例(Singleton)模式解决的是实体对象个数的问题,除了单例模式外,其它创建型模式解决的
都是new对象所带的耦合关系。

    工厂方法(Factory Method)、抽象工厂(Abstract Factory)、生成器(Builder)模式都需要一
个额外的工厂类来负责实例化“易变对象”,而原型(Prototype)模式则是通过原型(一个特殊的
工厂类)来克隆“易变对象”。

    如果遇到“易变类”,起初的设计通常从工厂方法模式开始,当遇到更多的复杂变化时再考虑重
构为其他三种模式(抽象工厂、生成器、原型)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值