Как убрать декораторы из строя в C # - PullRequest
2 голосов
/ 07 октября 2011

Я пытаюсь реализовать простое приложение, которое позволяет мне выбирать дополнения в автомобиле.Каждый дополнительный элемент является декоратором для базового класса Car.

Допустим, я делаю следующее

Car p = new FordFusion();
p = new ElectricWindows(p);
p = new LeatherSeatings(p);
p = new Airbags(p);

, тогда моим объектом p будет Ford Fusion с электрическими окнами, кожаными сиденьями и подушками безопасности..

Мне нужно, чтобы пользователь удалил декораторы не по порядку, как, скажем, снял электрические стеклоподъемники, не снимая кожаные сидения и подушки безопасности

Ответы [ 4 ]

3 голосов
/ 07 октября 2011

Похоже, что шаблон декоратора может быть не лучшим способом моделирования вашего домена.Ваши декораторы действительно должны изменить поведение автомобиля?Или они просто добавляют к стоимости / цене?

Вы пробовали иметь коллекцию ICarFeatures в качестве члена класса Car?ICarFeature может иметь метод GetCost или что-то в этом роде, что позволяет суммировать общую стоимость автомобиля.

0 голосов
/ 07 октября 2011

Мой ответ предполагает, что вы не откажетесь от подхода декоратора.

В вашем вопросе вы оговариваете возможность удалить Decorators не по порядку, это, в сущности, заставляет рекомендовать подход Undo/Redo или Decorate/UnDecorate.

Я подумал, что вы можете использовать шаблон Memento. Отслеживание состояния Car и какие Decorators применяются. Удаляя декоратор, вы в основном перемещаетесь по стеку примененных декораторов до желаемого состояния и восстанавливаете объект Car до этого состояния (ранее применялось удаление декоратора). Затем вам нужно будет повторно применить декораторы, которые будут действовать после этого. Возможно, это не оптимальное решение, но оно имеет наименьшее влияние на ваш текущий дизайн.

0 голосов
/ 07 октября 2011

Я бы, вероятно, решил эту проблему с помощью Цепочка ответственности . Я бы создал интерфейс обработчика

public interface IAccessoryHandler
{ 
  bool CanHandle( UserOption option );  // UserOption is an enum of Electric Window etc.

  Handle( Car car ); 
}

Затем я создал бы реализации обработчика, то есть ElectricWindowHandler, LeatherHandler и т. Д., Например, CanHandle () => if option == UserOption.electric then Handle () => car.Accessories.Add (new ElectricWindow);

Каждый раз, когда пользователь меняет параметры, я очищаю коллекцию автомобильных аксессуаров, делаю предисловие по выбранным параметрам пользователя и запускаю автомобильный объект по цепочке. К концу цепочки у вас в машине появятся правильные аксессуары.

0 голосов
/ 07 октября 2011

Может иметь централизованные объекты, которые сообщают вам, для какой модели какие функции устарели, так что вам не нужно полностью менять каждый шаблон декоратора.Просто небольшая модификация в них, я имею в виду, прежде чем ElectricWindows возвращает объект Car, он проверяет, имеет ли он право на эту функцию.Надеюсь, у меня есть смысл !! ​​

...