• DOTA版设计模式——原型


    原型模式,说白了就是拷贝新对象,新对象是原来的对象一模一样。就像是孙悟空用毛吹出的N个孙悟空一样,他们都是一样的具有一样的状态。
    UML图:

    在C#中原型模式就是要实现Clone方法,完成对对象的拷贝,framework中已经有了这个接口我们不必去重新定义了(ICloneable)。
    C#中分为深拷贝和浅拷贝,浅拷贝这样实现即可:
            public object Clone()
            {
                
    return this.MemberwiseClone();
            }

    这样代码很简单,但是有一定弊端。C#中有两种类型,引用类型和值类型。引用类型是放在托管堆中的,值类型放在堆栈中。当执行MemberwiseClone方法是返回的对象的确与原对象相同。但是两者却有很大的关联。对于值类型没有问题,而类中的引用类型成员返回的是同一对象,也就是说假如有个孙悟空类,类中包含的值类型没有问题,然而孙悟空类包含引用类型(外形类,自定义类型)。大家知道孙悟空会72般变化,那么假如我让N个孙悟空中的一个变为和尚,那么其他的孙悟空也会变为和尚,这是因为对于引用类型(外形类)MemberwiseClone传递的是引用,没有新建类。用C++语言来说就是传递给了新孙悟空对象了外形类指针,一个变化将引起多个变化。要想各个对象是互不关联的需要进行深拷贝。
    测试代码:
                //浅拷贝
                LandpyForm.Form.OutputResult("浅拷贝:MemberwiseClone");
                DotaPatternLibrary.Protype.Hero hero 
    = new DotaPatternLibrary.Protype.Terrorblade();
                LandpyForm.Form.OutputResult(
    "英雄名称:" + hero.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + hero.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            hero.RoleProperty.power,
                                            hero.RoleProperty.nimble,
                                            hero.RoleProperty.intelligence));
                DotaPatternLibrary.Protype.Hero heroNew 
    = hero.Clone() as DotaPatternLibrary.Protype.Hero;
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNew.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNew.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNew.RoleProperty.power,
                                            heroNew.RoleProperty.nimble,
                                            heroNew.RoleProperty.intelligence));

                LandpyForm.Form.OutputResult(
    "升级==>");

                hero.Level 
    += 1;
                hero.RoleProperty.power 
    += 1.9m;
                hero.RoleProperty.nimble 
    += 3.2m;
                hero.RoleProperty.intelligence 
    += 1.75m;
                LandpyForm.Form.OutputResult(
    "英雄名称:" + hero.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + hero.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            hero.RoleProperty.power,
                                            hero.RoleProperty.nimble,
                                            hero.RoleProperty.intelligence));
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNew.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNew.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNew.RoleProperty.power,
                                            heroNew.RoleProperty.nimble,
                                            heroNew.RoleProperty.intelligence));
                
    //深拷贝
                LandpyForm.Form.OutputResult("深拷贝:新对象");
                DotaPatternLibrary.Protype.HeroForDeepCopy heroDeep 
    = new DotaPatternLibrary.Protype.Syllabear();
                LandpyForm.Form.OutputResult(
    "英雄名称:" + heroDeep.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + heroDeep.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroDeep.RoleProperty.power,
                                            heroDeep.RoleProperty.nimble,
                                            heroDeep.RoleProperty.intelligence));
                DotaPatternLibrary.Protype.HeroForDeepCopy heroNewDeep 
    = heroDeep.Clone() as DotaPatternLibrary.Protype.HeroForDeepCopy;
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNewDeep.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNewDeep.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNewDeep.RoleProperty.power,
                                            heroNewDeep.RoleProperty.nimble,
                                            heroNewDeep.RoleProperty.intelligence));

                LandpyForm.Form.OutputResult(
    "升级==>");

                heroDeep.Level 
    += 1;
                heroDeep.RoleProperty.power 
    += 1.9m;
                heroDeep.RoleProperty.nimble 
    += 3.2m;
                heroDeep.RoleProperty.intelligence 
    += 1.75m;
                LandpyForm.Form.OutputResult(
    "英雄名称:" + heroDeep.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + heroDeep.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroDeep.RoleProperty.power,
                                            heroDeep.RoleProperty.nimble,
                                            heroDeep.RoleProperty.intelligence));
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNewDeep.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNewDeep.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNewDeep.RoleProperty.power,
                                            heroNewDeep.RoleProperty.nimble,
                                            heroNewDeep.RoleProperty.intelligence));
                
    //深拷贝
                LandpyForm.Form.OutputResult("深拷贝:序列化");
                DotaPatternLibrary.Protype.HeroForSerializable heroSerializable 
    = new DotaPatternLibrary.Protype.Puck();
                LandpyForm.Form.OutputResult(
    "英雄名称:" + heroSerializable.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + heroSerializable.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroSerializable.RoleProperty.power,
                                            heroSerializable.RoleProperty.nimble,
                                            heroSerializable.RoleProperty.intelligence));
                DotaPatternLibrary.Protype.HeroForSerializable heroNewSerializable 
    = heroSerializable.Clone() as DotaPatternLibrary.Protype.HeroForSerializable;
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNewSerializable.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNewSerializable.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNewSerializable.RoleProperty.power,
                                            heroNewSerializable.RoleProperty.nimble,
                                            heroNewSerializable.RoleProperty.intelligence));

                LandpyForm.Form.OutputResult(
    "升级==>");

                heroSerializable.Level 
    += 1;
                heroSerializable.RoleProperty.power 
    += 1.9m;
                heroSerializable.RoleProperty.nimble 
    += 3.2m;
                heroSerializable.RoleProperty.intelligence 
    += 1.75m;
                LandpyForm.Form.OutputResult(
    "英雄名称:" + heroSerializable.Name);
                LandpyForm.Form.OutputResult(
    "英雄级别:" + heroSerializable.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroSerializable.RoleProperty.power,
                                            heroSerializable.RoleProperty.nimble,
                                            heroSerializable.RoleProperty.intelligence));
                LandpyForm.Form.OutputResult(
    "复制英雄名称:" + heroNewSerializable.Name);
                LandpyForm.Form.OutputResult(
    "复制英雄级别:" + heroNewSerializable.Level);
                LandpyForm.Form.OutputResult(String.Format(
    "复制英雄属性---力量:{0},敏捷{1},智力{2}",
                                            heroNewSerializable.RoleProperty.power,
                                            heroNewSerializable.RoleProperty.nimble,
                                            heroNewSerializable.RoleProperty.intelligence));

    完整代码:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;

    using DotaCommon;

    namespace DotaPatternLibrary.Protype
    {
        
    /// <summary>
        
    /// 角色属性
        
    /// </summary>
        [Serializable]
        
    public class RoleProperty
        {
            
    public decimal power;
            
    public decimal nimble;
            
    public decimal intelligence;
        }

        
    /// <summary>
        
    /// 英雄
        
    /// </summary>
        public abstract class Hero : ICloneable
        {
            
    protected int _level;
            
    protected string _name;
            
    protected RoleProperty _roleProperty;

            
    public string Name
            {
                
    get { return _name; }
                
    set { _name = value; }
            }

            
    public RoleProperty RoleProperty
            {
                
    get { return _roleProperty; }
                
    set { _roleProperty = value; }
            }


            
    public int Level
            {
                
    get { return _level; }
                
    set { _level = value; }
            }

            
    public object Clone()
            {
                
    return this.MemberwiseClone();
            }
        }

        
    /// <summary>
        
    /// 英雄
        
    /// </summary>
        public abstract class HeroForDeepCopy : ICloneable
        {
            
    protected int _level;
            
    protected string _name;
            
    protected RoleProperty _roleProperty;

            
    public string Name
            {
                
    get { return _name; }
                
    set { _name = value; }
            }
            
    public RoleProperty RoleProperty
            {
                
    get { return _roleProperty; }
                
    set { _roleProperty = value; }
            }
            
    public int Level
            {
                
    get { return _level; }
                
    set { _level = value; }
            }

            
    public abstract object Clone();
        }

        
    /// <summary>
        
    /// 英雄
        
    /// </summary>
        [Serializable]
        
    public abstract class HeroForSerializable : ICloneable
        {
            
    protected int _level;
            
    protected string _name;
            
    protected RoleProperty _roleProperty;

            
    public string Name
            {
                
    get { return _name; }
                
    set { _name = value; }
            }
            
    public RoleProperty RoleProperty
            {
                
    get { return _roleProperty; }
                
    set { _roleProperty = value; }
            }
            
    public int Level
            {
                
    get { return _level; }
                
    set { _level = value; }
            }

            
    public object Clone()
            {
                
    object returnValue = null;
                
    using (MemoryStream memoryStream = new MemoryStream())
                {
                    IFormatter formatter 
    = new BinaryFormatter();
                    formatter.Serialize(memoryStream, 
    this);
                    memoryStream.Seek(
    0, SeekOrigin.Begin);
                    returnValue 
    = formatter.Deserialize(memoryStream);
                }
                
    return returnValue;
            }
        }

        
    /// <summary>
        
    /// 灵魂守卫
        
    /// </summary>
        public class Terrorblade : Hero
        {
            
    public Terrorblade()
            {
                
    this._level = 1;
                
    this._name = "灵魂守卫(Terrorblade)";
                RoleProperty roleProperty 
    = new RoleProperty();
                roleProperty.power 
    = 15;
                roleProperty.nimble 
    = 22;
                roleProperty.intelligence 
    = 15;
                
    this._roleProperty = roleProperty;
            }
        }

        
    /// <summary>
        
    /// 德鲁伊
        
    /// </summary>
        public class Syllabear : HeroForDeepCopy
        {
            
    public Syllabear()
            {
                
    this._level = 1;
                
    this._name = "德鲁伊(Syllabear)";
                RoleProperty roleProperty 
    = new RoleProperty();
                roleProperty.power 
    = 17;
                roleProperty.nimble 
    = 24;
                roleProperty.intelligence 
    = 13;
                
    this._roleProperty = roleProperty;
            }

            
    public override object Clone()
            {
                Syllabear syllabear 
    = new Syllabear();
                syllabear.Name 
    = Name;
                syllabear.Level 
    = Level;
                RoleProperty roleProperty 
    = new RoleProperty();
                roleProperty.intelligence 
    = RoleProperty.intelligence;
                roleProperty.nimble 
    = RoleProperty.nimble;
                roleProperty.power 
    = RoleProperty.power;
                syllabear.RoleProperty 
    = roleProperty;
                
    return syllabear;
            }
        }

        
    /// <summary>
        
    /// 精灵龙
        
    /// </summary>
        [Serializable]
        
    public class Puck : HeroForSerializable
        {
            
    public Puck()
            {
                
    this._level = 1;
                
    this._name = "精灵龙(Puck)";
                RoleProperty roleProperty 
    = new RoleProperty();
                roleProperty.power 
    = 15;
                roleProperty.nimble 
    = 22;
                roleProperty.intelligence 
    = 25;
                
    this._roleProperty = roleProperty;
            }
        }
    }
  • 相关阅读:
    扩展欧几里得(exgcd)与同余详解
    卡常模板
    文艺平衡树(区间翻转)
    Motto
    PKUWC2019划水记
    【模板】Splay(洛谷P3391)
    【PKUSC2018】最大前缀和
    【PKUWC2018】随机算法
    【PKUWC2018】Slay the Spire
    【PKUWC2018】Minimax
  • 原文地址:https://www.cnblogs.com/pangxiaoliang/p/1531574.html
Copyright © 2020-2023  润新知