首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用装饰器模式实现clone()

使用装饰器模式实现clone()
EN

Stack Overflow用户
提问于 2010-12-22 03:20:10
回答 1查看 479关注 0票数 0

使用装饰器模式实现clone()方法的最佳方式是什么?

在这个装饰器场景中:

var mario:Hero = new Mario();

mario = new HeroUpgrade(mario); //bigger moustache ;)

mario.clone(); //<--trying to grab a clone of the upgraded mario

然后(遵循装饰器模式)它将把clone()委托回原始的mario实例。因此,clone()将返回原始mario,而不是升级后的版本。

我意识到,与克隆相比,我可以从升级的Mario实例中抓取一个纪念品,并将其注入到mario的新实例中,但感觉应该有一个更简单的解决方案……

有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2010-12-22 08:48:06

装饰器添加了功能,因此您不必将所有内容都委托给原始的mario。

是的,你可以将克隆委托给原始的mario,但是你的装饰器会用它自己的大胡子来更新moustache属性,然后返回更新后的克隆;

更新以解释克隆:装饰器模式的全部要点是对包装的对象隐藏新功能,因此包装的对象不会克隆装饰的属性。您调用顶级装饰器的clone方法。装饰器重写Clone方法,以透明的方式添加自己的功能。

代码语言:javascript
复制
    public class Mario : ICloneable
    {
        public Mario()
        {
            MoustacheSize = 1;
        }

        private double _moustacheSize;
        public virtual double MoustacheSize
        {
            get { return _moustacheSize; }
            internal set { _moustacheSize = value; }
        }

        public virtual object Clone()
        {
            var clone = new Mario();
            clone.MoustacheSize = this.MoustacheSize;
            return clone;
        }
    }

    public class HeroUpgradeDecorator : Mario
    {
        public HeroUpgradeDecorator(Mario mario)
        {
            _inner = mario;
        }

        private Mario _inner;

        public override double MoustacheSize
        {
            get
            {
                return _inner.MoustacheSize * 1.2; // 20% increase in moustache size
            }
        }

        public override object Clone()
        {
            var clone = new Mario();
            clone.MoustacheSize = this.MoustacheSize;
            return clone;
        }
    }

    static void Main(string[] args)
    {
        var mario = new Mario();
        Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize);

        Console.WriteLine("Upgrading...");
        mario = new HeroUpgradeDecorator(mario); // variable mario now points to the decorator
        Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize);

        Console.WriteLine("Upgrading again...");
        mario = new HeroUpgradeDecorator(mario); // variable mario now points to the 2nd decorator
        Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize);

        Console.ReadLine();
    }

此控制台应用程序的输出为:

代码语言:javascript
复制
Mario, with moustache size: 1
Upgrading...
Mario, with moustache size: 1.2
Upgrading again...
Mario, with moustache size: 1.44

或者,如果有很多属性需要克隆,装饰器可以这样做:

代码语言:javascript
复制
        public override object Clone()
        {
            var clone = (Mario)_inner.Clone();
            clone.MoustacheSize = this.MoustacheSize;
            return clone;
        }

装饰器使用原始对象的clone方法,然后更新它自己更改的属性。但最终的结果仍然是装饰者负责的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4503049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档