Декоратор добавляет функциональность, поэтому вы не делегируете все обратно оригинальному mario.
Да, вы можете делегировать клон исходному mario, но ваш декоратор затем обновит свойство усов своими собственными большими усами, а затем вернет обновленный клон;
ОБНОВЛЕНО, чтобы объяснить клонирование:
Весь смысл шаблона декоратора состоит в том, чтобы скрыть новую функциональность от обернутого объекта, чтобы обернутый объект не клонировал декорированные свойства. Вы вызываете метод клонирования декоратора верхнего уровня. Декоратор переопределяет метод 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;
}
Декоратор использует метод clone исходного объекта, а затем обновляет свойства, которые он сам меняет. Но за конечный результат отвечает декоратор.