策略模式允许您change运行时使用的东西的实现。
装饰器模式允许您在运行时使用附加功能来增强(或添加)现有功能。
关键的区别在于change vs augment
在与之链接的问题之一中,您还指出,使用策略模式,消费者知道存在不同的选项,而使用装饰器模式,消费者不会意识到附加功能。
举个例子,假设您正在编写一些内容来对元素集合进行排序。所以你写一个接口ISortingStrategy
然后您可以实施几种不同的排序策略BubbleSortStrategy
, QuickSortStrategy
, RadixSortStrategy
,那么您的应用程序将根据现有列表的某些条件选择最合适的策略来对列表进行排序。例如,如果列表中的项目少于 10 个,我们将使用RadixSortStrategy
,如果自上次排序以来添加到列表中的项目少于 10 个,我们将使用BubbleSortStrategy
否则我们将使用QuickSortStrategy
.
我们正在运行时更改排序类型(以便根据一些额外信息提高效率)。这就是策略模式。
现在想象一下,有人要求我们提供每个排序算法用于进行实际排序的频率的日志,并将排序限制为管理员用户。我们可以通过创建一个装饰器来添加这两个功能,该装饰器增强了any 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");
}
}
}