Стратегия позволяет изменить реализацию того, что используется во время выполнения.
Шаблон декоратора позволяет вам дополнять (или добавлять) существующие функциональные возможности с дополнительной функциональностью во время выполнения.
Основное различие заключается в изменения против увеличивающие
В одном из вопросов, которые вы связаны с ним также указывает на то, что с шаблоном стратегии потребитель знает, что различные варианты существуют, в то время как с шаблон декоратора, потребитель не будет знать о дополнительных функциях.
В качестве примера предположим, что вы пишете что-то, чтобы отсортировать коллекцию элементов. Таким образом, вы пишете интерфейс ISortingStrategy
, после чего вы можете реализовать несколько различных стратегий сортировки BubbleSortStrategy
, QuickSortStrategy
, RadixSortStrategy
, то ваше приложение, основанное на некоторых критериях существующего списка, выбирает наиболее подходящую стратегию для сортировки списка. Так, например, если в списке меньше 10 предметов, мы будем использовать RadixSortStrategy
, если в списке было добавлено менее 10 элементов с последнего сортировки, мы будем использовать BubbleSortStrategy
, иначе мы будем использовать QuickSortStrategy
.
Мы меняем тип сортировки во время выполнения (чтобы быть более эффективным на основе дополнительной информации). Это шаблон стратегии.
Теперь представьте, что кто-то попросит нас предоставить журнал того, как часто каждый алгоритм сортировки используется для фактического сортировки и для ограничения сортировки для пользователей-администраторов. Мы можем добавить обе эти части функциональности, создав декоратор, который усилители любойISortingStrategy
. Мы могли бы создать декоратор, который регистрирует, что он использовался для сортировки и типа стратегии сортировки сортировки. И мы могли бы добавить еще один декоратор, который бы проверял, был ли текущий пользователь администратором, прежде чем он назвал украшенную стратегию сортировки.
Здесь мы добавляем новые функциональные возможности любой стратегии сортировки с помощью декоратора, но не выгрузив функциональность сортировки ядра (мы использовали различные стратегии, чтобы изменить это)
Вот пример того, как декораторы могут выглядеть так:
public interface ISortingStrategy
{
void Sort(IList<int> listToSort);
}
public class LoggingDecorator : ISortingStrategy
{
private ISortingStrategy decorated;
public LoggingDecorator(ISortingStrategy decorated)
{
this.decorated=decorated;
}
void Sort(IList<int> listToSort)
{
Log("sorting using the strategy: " + decorated.ToString();
decorated.Sort(listToSort);
}
}
public class AuthorisingDecorator : ISortingStrategy
{
private ISortingStrategy decorated;
public AuthorisingDecorator(ISortingStrategy decorated)
{
this.decorated=decorated;
}
void Sort(IList<int> listToSort)
{
if (CurrentUserIsAdministrator())
{
decorated.Sort(listToSort);
}
else
{
throw new UserNotAuthorizedException("Only administrators are allowed to sort");
}
}
}
Спасибо действительно хороший пример. –
Для того, чтобы эти два класса были декораторами и чтобы клиентские вызовы были прозрачными (вызывая интерфейс 'ISortingStrategy'), они должны внедрять' ISortingStrategy', а также иметь его как зависимость –
@kobac. Исправлена.Спасибо –