Здравствуйте.
В примерах существует конкретный объект, который декорируем. Использую стандартную имплементацию банды 4-х.
Например кофе обворачиваем в 3 сахара и обворачиваем в 1 молоко и распечатываем ингридиенты и цену —
ICofeeProduct prod2 = new Sugar(new Sugar(new Sugar(new Milk(new DarkRoast()))));
Console.WriteLine("I am {0}, my cost is {1}", prod2.Name(), prod2.Cost());
DarkRoast — конкретный объект, остальное — декорация.
Но, по-моему возникают 2 проблемы:
1. Надо помнить, кто конкретный объект, а кто декорация
т.е так:
ICofeeProduct prod2 = new Sugar(new Sugar(new DarkRoast(new Milk(new Sugar()))));
работать не будет, хотя по-моему смысл не поменялся: 3 сахара + 1 молоко + 1 кофе
2. Невозможно сделать 2 DarkRoast (типа, сильный кофе)
т.е так:
ICofeeProduct prod2 = new Sugar(new Sugar(new Sugar(new DarkRoast(new DarkRoast()))));
работать не будет
Я подумал о следующей реализации шаблона (Null object шаблон мне подсказали):
public interface ICofeeProduct
{
double Cost();
string Name();
}
public class Empty : ICofeeProduct
{
public double Cost() { return 0.0; }
public string Name() { return ""; }
}
public class DarkRoast : ICofeeProduct
{
ICofeeProduct _product;
public DarkRoast(ICofeeProduct prod = null)
{
_product = (prod == null) ? new Empty() : prod;
}
public double Cost() { return 2.5 + _product.Cost(); }
public string Name() { return "DarkRoast " + _product.Name(); }
}
public class Milk : ICofeeProduct
{
ICofeeProduct _product;
public Milk(ICofeeProduct prod = null)
{
_product = (prod == null) ? new Empty() : prod;
}
public double Cost() { return 0.5 + _product.Cost(); }
public string Name() { return "With milk " + _product.Name(); }
}
public class Sugar : ICofeeProduct
{
ICofeeProduct _product;
public Sugar(ICofeeProduct prod = null)
{
_product = (prod == null) ? new Empty() : prod;
}
public double Cost() { return 0.2 + _product.Cost(); }
public string Name() { return "With sugar " + _product.Name(); }
}
Я по-своему решил мои проблемы, и теперь так:
ICofeeProduct prod1 = new Sugar(new Sugar(new DarkRoast(new Milk(new Sugar()))));
ICofeeProduct prod2 = new Sugar(new Sugar(new Sugar(new DarkRoast(new DarkRoast()))));
работает.
Какие минусы есть у такой имплементации декоратора?
Спасибо