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

发布于 2024-10-08 08:58:16 字数 389 浏览 3 评论 0原文

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

在此装饰器场景中:

var mario:Hero = new Mario();
马里奥=新的英雄升级(马里奥); //更大的胡子;)
马里奥.克隆(); //<--尝试获取升级后的马里奥的克隆

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

我意识到,我可以从升级的马里奥实例中获取一个纪念品,并将其注入新的马里奥实例中,而不是克隆,但感觉应该有一个更简单的解决方案......

有什么建议吗?

What's the best way to implement a clone() method using the decorator pattern?

In this decorator scenario:

var mario:Hero = new Mario();
mario = new HeroUpgrade(mario); //bigger moustache ;)
mario.clone(); //<--trying to grab a clone of the upgraded mario

then (following the Decorator pattern) it would delegate the clone() back to the original mario instance. So clone() would return the original mario rather than the upgraded version.

I realize that, rather than cloning, I could grab a memento off of the upgraded mario instance and inject that into a new instance of Mario, but it feels like there should be a simpler solution...

Any tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情痴 2024-10-15 08:58:16

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

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

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

    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();
    }

该控制台应用程序的输出是:

Mario, with moustache size: 1
Upgrading...
Mario, with moustache size: 1.2
Upgrading again...
Mario, with moustache size: 1.44

或者,如果有很多属性需要克隆装饰器,则可以执行以下操作:

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

装饰器使用原始对象的克隆方法,然后更新它本身更改的属性。但最终结果仍然由装饰器负责。

A decorator adds functionality, so you don't delegate everything back to the original mario.

Yes, you can delegate clone to the original mario, but your decorator will then update the moustache property with it's own bigger moustache and then return the updated clone;

UPDATED to explain cloning:
The whole point of the decorator pattern is to hide the new functionality from the wrapped object, so the wrapped object doesn't clone the decorated properties. You call the clone method of the top level decorator. The decorator overrides the Clone method to add it's own functionality in a transparent way.

    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();
    }

output of this console application is:

Mario, with moustache size: 1
Upgrading...
Mario, with moustache size: 1.2
Upgrading again...
Mario, with moustache size: 1.44

Alternatively if there are a lot of properties to clone the decorator can do this:

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

The decorator uses the clone method of the original object, and then updates the properties it changes itself. But it's still the decorator that is responsible for the end result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文