Большинство из вас знает пример pizza / cofee для шаблона декоратора.
Pizza* pizza1 = BigPizzaDecorator(MushromDecorator(SimplePizza()));
Pizza* pizza2 = MushromDecorator(BigPizzaDecorator(SimplePizza()));
два объекта ведут себя одинаково, но не полностью, в частности, если у вас нет -коммутативная операция, например:
BigPizzaDecorator::price() { return 10 + PizzaDecorator::price(); } // this is commutative
BigPizzaDecorator::name() { return "big " + PizzaDecorator::name(); } // this is not commutative
Таким образом, цена на pizza1
и pizza2
одинакова, но имя не совпадает, например, первое должно быть "Big грибная пицца »
, вторая « Большая грибная пицца »
. Первая английская правильная (наверное, лучше было бы« Большая пицца с грибами », но это не так важно).
Книга "Head first" указывает на эту проблему в примере Cofee:
Когда вам нужно заглянуть на несколько уровней в цепочку декораторов, вы начинают выталкивать декоратор за пределы его истинных намерений.
Тем не менее, такие вещи возможны. Представьте себе приправу декоратор, который анализирует окончательное описание и может напечатать «Mocha, Whip, Mocha »как« Whip, Double Mocha ».
как лучше всего это сделать? ( оператор <
?)