zoukankan      html  css  js  c++  java
  • 设计模式05: Prototype 原型模式(创建型模式)

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

    依赖关系的倒置
    抽象不应该依赖于实现细节,细节应该依赖于抽象。对所有的设计模式都是这样的。

    -抽象A直接依赖于实现细节b

    -抽象A依赖于抽象B,实现细节b依赖于抽象B

    动机(Motivation)

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

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

    意图(Intent)

    使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。——《设计模式》GoF

    示例代码:

        /// <summary>
        /// 普通兵
        /// </summary>
        public abstract class NormalActor
        {
            public abstract NormalActor Clone();
        }
        /// <summary>
        /// 飞行兵
        /// </summary>
        public abstract class FlyActor
        {
            public abstract FlyActor Clone();
        }
        /// <summary>
        /// 水兵
        /// </summary>
        public abstract class WaterActor
        {
            public abstract WaterActor Clone();
        }
        public class NormalActorA : NormalActor
        {
            public override NormalActor Clone()
            {
                //或者强转成NormalActorA也行
                //return (NormalActorA)this.MemberwiseClone();
                return (NormalActor)this.MemberwiseClone();//浅拷贝,对于值类型+string类型是OK的,但是如果有其他的引用类型就不行了(clone的只是地址)
                //通过序列化来解决浅拷贝的问题
            }
        }
        public class FlyActorA : FlyActor
        {
            public override FlyActor Clone()
            {
                throw new NotImplementedException();
            }
        }
        public class WaterActorA : WaterActor
        {
            public override WaterActor Clone()
            {
                throw new NotImplementedException();
            }
        }
        public class GameSystem
        {
            public void Run()
            {
                NormalActorA normalActor1 = new NormalActorA();//GameSystem(抽象)依赖于NormalActorA(具体)了
                NormalActorA normalActor2 = new NormalActorA();
                NormalActorA normalActor3 = new NormalActorA();
                NormalActorA normalActor4 = new NormalActorA();
    
                FlyActorA flyActor1 = new FlyActorA();
                FlyActorA flyActor2 = new FlyActorA();
    
                WaterActorA waterActor1 = new WaterActorA();
                WaterActorA waterActor2 = new WaterActorA();
            }
            //======由于上面的Run导致抽象依赖于具体了,所以要改为下面的依赖于抽象=======>
            public void Run(NormalActor normalActor, FlyActor flyActor, WaterActor waterActor)
            {   //NormalActor为NormalActorA的抽象
                NormalActor normalActor1 = normalActor.Clone();
                NormalActor normalActor2 = normalActor.Clone();
                NormalActor normalActor3 = normalActor.Clone();
                NormalActor normalActor4 = normalActor.Clone();
    
                FlyActor flyActor1 = flyActor.Clone();
                FlyActor flyActor2 = flyActor.Clone();
    
                WaterActor waterActor1 = waterActor.Clone();
                WaterActor waterActor2 = waterActor.Clone();
            }
        }

    Prototype模式的几个要点

    Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。

    Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使我们非常灵活地创建“拥有某些稳定接口”的新对象——所需的工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。

    Prototype模式中的Clone方法可用利用.NET中的Object类的MemberwiseClone()方法或者序列化(可以实现深拷贝)来实现。

    有关创建型模式的讨论

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

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

    如果遇到“易变类”,起初的设计通常从Factory Method开始,当遇到更多复杂变化时,在考虑重构为其他三种工厂模式(Abstract Factory,Builder,Prototype)。

  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4714908.html
Copyright © 2011-2022 走看看