策略模式V/S装饰模式

Nir*_*ani 48 design-patterns decorator strategy-pattern

我刚遇到两种模式.

  1. 战略模式

  2. 装饰

策略模式: -

策略模式提供了几种可用于执行特定操作或任务的算法.

装饰图案: -

装饰器模式为组件添加了一些功能.

事实上,我发现策略模式和装饰模式也可以互换使用.

这是链接: - 何时以及如何应用策略模式而不是装饰模式?

Strategy Pattern和Decorator Pattern有什么区别?

什么时候应该使用策略模式,何时应该使用Decorator模式?

用同一个例子解释两者之间的区别.

Sam*_*der 92

策略模式允许您更改运行时使用的某些内容的实现.

装饰器模式允许您在运行时使用其他功能扩充(或添加)现有功能.

关键的区别在于变化增强

在与其链接的一个问题中,还指出,使用策略模式,消费者意识到存在不同的选项,而使用装饰器模式,消费者不会意识到附加功能.

举个例子,假设您正在编写一些东西来对元素集合进行排序.所以,你写一个接口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");
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为了让这两个类成为装饰器并且客户端调用是透明的(针对 `ISortingStrategy` 接口调用),它们应该实现 `ISortingStrategy` 并将其作为依赖项 (2认同)

Rav*_*abu 10

Strategy_pattern

  1. 定义一系列算法,
  2. 封装每个算法,和
  3. 使算法在该族中可互换.

必须在运行时动态更改算法时使用策略模式.

装饰

装饰器模式在运行时动态更改对象的功能,而不会影响对象的现有功能.

何时使用:

  1. 动态添加其他功能/职责
  2. 动态删除功能/职责
  3. 避免过多的子类化以增加额外的责任.

缺点:

  1. 过度使用开放封闭原则(开放用于扩展,关闭用于修改).在代码最不可能更改的地方谨慎使用此功能.
  2. 太多的小类会增加维护开销.

关键区别:

策略允许您更改对象的内容.装饰器让你改变皮肤.

几个有用的帖子:

何时使用装饰器模式?

战略模式的现实世界范例

战略由sourcemaking


kir*_*son 8

归结为:使用策略来选择一项核心功能。使用装饰器添加额外的功能。策略是我们正在制作的蛋糕,装饰者是我们添加到其中的所有漂亮装饰。


Mag*_*ngs 5

策略是模式用于"封装什么变化".它允许您定义可在运行时互换的算法.例如(取自Head First Design Patterns的示例):

假设你有一个鸭子模拟器.你想让你的鸭子物体飞翔.你可以使用继承,但它很快就会变得混乱.有些鸭子不会飞(例如橡皮鸭).这样做的方法是将所谓的变化(即飞行行为)封装到自己的类中,例如实现IFlybehaviour.然后,您可以使用合成而不是继承,并将IFlybehaviour注入到鸭子对象中.然后,您还可以使用一种方法来设置此飞行行为,以便可以在运行时更改飞行行为.这基本上就是战略模式.

装饰器模式用于在运行时向对象添加功能.它允许您将对象包装在对象中.装饰器必须与它们装饰的对象具有相同的超类型.这允许您在"最外层包装器"上调用方法,然后您可以通过装饰器层向下调用相同的方法.它基本上是一种比子类化更灵活的方法.

至于你选择哪一个取决于你想要解决的问题.您是否希望拥有一系列可在运行时互换的algorthims,或者您是否希望在运行时动态地向对象添加更多功能?

"Head first design patterns"这本书很好地解释了这一点(可能比我好得多)IMO所以如果你有机会的话,值得一读.

祝好运.


Mar*_*mus 5

策略是选择一种算法。

Collections.sort(list, comparator); // comparator is the strategy
Run Code Online (Sandbox Code Playgroud)

装饰器正在包装一个对象,同时保持相同的类型。

in = new BufferedInputStream(in);
Run Code Online (Sandbox Code Playgroud)