标签: strategy-pattern

帮助战略模式

我一直在经历Head First Design Patterns(最近刚刚进入)并且我正在阅读关于策略模式的内容,我想到它可能是一种很好的方式来实现计算税收等的常用方法.我在工作中使用的特定对象,但我有一个问题.

这就是我的想法:

public interface ITax
{
    decimal ProvincialTaxRate { get; set; } // Yes, I'm Canadian :)
    decimal CalculateTax(decimal subtotal);
}

public SaskatchewanTax
{
    public decimal ProvincialTaxRate { get; set; }

    public SaskatchewanTax()
    {
        ProvincialTaxRate = new decimal(0.05f);
    }

    public decimal CalculateTax(subtotal)
    {
        return ProvincialTaxRate * subtotal + FederalTaxRate * subtotal;
    }
}

public OntarioTax
{
    public decimal ProvincialTaxRate { get; set; }

    public OntarioTax()
    {
        ProvincialTaxRate = new decimal(0.08f);
    }

    public decimal CalculateTax(decimal subtotal)
    {
        return …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns strategy-pattern

10
推荐指数
1
解决办法
1422
查看次数

在策略模式中,策略可以将Context作为参数


反馈摘要

我现在将关闭这个(我想没有更多的反馈),并试着总结一下我的理解

  1. 使用"Context"作为我的策略的参数引入了应该避免的紧密耦合,并且还可能迫使我暴露应该保留在类中的属性.
  2. 为了最小化耦合,最好提供所需的值或至少使用接口而不是具体类型的策略.

我正在努力清楚地了解战略模式,并且我问自己,策略取决于上下文是好还是坏.

让我们采取以下经典实现

//The strategy
interface IStrategy  
{  
  void Execute();  
}  

class ConcreteStrategyA : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
  }
}

class ConcreteStrategyB : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
  }
}

//The context
class Context
{
  IStrategy strategy;

  // Constructor
  public Context(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void UpdateContext(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void Execute()
  {
    strategy.Execute();
  }
}
Run Code Online (Sandbox Code Playgroud)

我见过的所有例子都有非常简单的策略,它们采用基本参数(例如整数).我想知道的是,如果策略使用Context来完成工作,那么是否存在问题.

它会给出类似的东西

//The …
Run Code Online (Sandbox Code Playgroud)

design-patterns strategy-pattern

10
推荐指数
2
解决办法
4615
查看次数

策略模式中的参数不同

有时在使用策略模式时,我发现一些算法实现不需要相同的参数列表.

例如

    public interface Strategy{
     public void algorithm(int num);
    }

    public class StrategyImpl1 implements Strategy{
     public void algorithm(int num){
       //num is needed in this implementation to run algorithm
     }
    }

    public class StrategyImpl2 implements Strategy{
     public void algorithm(int num){
       //num is not needed in this implementation to run algorithm but because im using same
       strategy interface I need to pass in parameter
     }

}
Run Code Online (Sandbox Code Playgroud)

我应该使用不同的设计模式吗?

design-patterns strategy-pattern

10
推荐指数
1
解决办法
2839
查看次数

桥梁与战略模式

我知道,这个问题被多次询问,但我做了一些研究,但仍然没有得到它,可能你可以帮助我:正如很多次说的那样,UML几乎是一样的.此外,实现和想法或多或少相同:您可以定义一个Interface,而不是子类型,它封装了一些逻辑,让它传递给一个抽象.所以,即使是微软博客的人

https://blogs.msdn.microsoft.com/gyanjadal/2015/01/05/difference-between-strategy-and-bridge-patterns/说:

简单的答案是"它们相似但不同".实现类似但意图不同.举一个类比,城市公交车和校车都是类似的车辆,但它们用于不同的目的.一种用于在城市的各个部分之间运送人员作为通勤服务.另一个用于将孩子送到学校.

"如果它看起来像一只鸭子,看起来像一只鸭子,但它打算成为一只天鹅,它可以是其中之一",这就是我在这里读到的.

因为我还没有得到它,所以我深入挖掘:

https://social.msdn.microsoft.com/Forums/en-US/08775d39-2de0-4598-8872-df21f681b7b3/strategy-vs-bridge-patterns?forum=architecturegeneral

此线程也不添加任何新内容,除了:

它们在表面上看起来也一样.我看到的主要区别在于,在Bridge模式中,抽象是对象的PART,但在Strategy模式中,抽象是由对象执行的.

但是,如果我们阅读战略的定义:

定义一系列算法,封装每个算法,并使它们可互换.策略允许算法独立于使用它的客户端.

没有任何定义,如何应用该战略.它也可以很容易地成为摘要上的接口,与LINQ-Orderby等常见的策略实现完全相同.

关于这个主题的另一个兴趣是:

http://game-engineering.blogspot.ch/2008/07/bridge-pattern-vs-strategy-pattern.html

这个话题的主要部分:

当你想要改变行为时,你会说"策略",而你不是通过编写不同的对象而是通过引入类层次来实现.当您希望改变界面和实现时,您会说"Bridge".在这两种情况下,您都可以为不断变化的实施提供灵活性; 在Bridge中,您还希望界面能够改变.

这可能是主要区别吗?由于执行器和抽象是如此松散耦合,我可以改变执行器的接口,抽象不必关心?这听起来很合理,但是由于它们是有联系的,所以也不会有抽象改变吗?这不会破坏信息隐藏和DRY等所有其他原则吗?

我还看了很多例子,我不会为了这个地方而添加这些例子,我找不到这些模式的例子,我无法改变以适应另一个.无论是通过Interface-Property还是参数.

我在这里错过了吗?可能任何人都有一个真实生活的例子"我想使用策略,但Bridge确实更合适",反之亦然,例如?

编辑:为什么我为这个主题辩护(再次)?首先,所提到的线程的接受答案如下

据我了解,当你抽象出可以从外部源提供的行为时(例如,config可以指定加载一些插件程序集),你正在使用策略模式,并且当你使用时你正在使用桥接模式相同的结构使你的代码更整洁.实际的代码看起来非常相似 - 你只是因为略有不同的原因而应用这些模式.

我在之前的解释中已经提到,外部源的抽象行为正是Strategy-和Bridge-Pattern的定义.

当你使用相同的结构使你的代码更整洁时,你正在使用桥接模式.

此外,策略模式使代码更整洁,因为它将整个构建块抽象出来,从而使代码收紧了很多.

我想任何阅读整个主题的人都会看到,这个主题的内容比这2个句子更多.

c# oop design-patterns bridge strategy-pattern

10
推荐指数
1
解决办法
1811
查看次数

Unity解析多个类

我如何获得microsoft unity来"构造"给定接口类型的类列表.

很简单的例子:

  List<IShippingCalculation> list = new List<IShippingCalculation>();
  list.Add(new NewYorkShippingCalculation());
  list.Add(new FloridaShippingCalculation());
  list.Add(new AlaskShippingCalculation());

  //Not What I want
  public void calcship(List<IShippingCalculation> list)
  {
    var info = new ShippingInfo(list);
    info.CalculateShippingAmount(State.Alaska)
  }

  //Somehow in unity, must i do this for all the concrete classes? 
  //how does it know to give a list.
  Container.RegisterType<IShippingInfo,new AlaskaShippingCalculation()>();??

  //What I want
  public void calcship(IShippingInfo info)
  {
    info.CalculateShippingAmount(State.Alaska)
  }
Run Code Online (Sandbox Code Playgroud)

谢谢!

c# unity-container strategy-pattern

9
推荐指数
2
解决办法
4931
查看次数

何时以及如何应用策略模式而不是装饰模式?

我正在学习设计模式并试图遵循Go4书.在页面:179,在装饰模式章节中,有一行说

"通过将策略的数量从一个扩展到一个开放式列表,我们可以递归地实现与嵌套装饰器相同的效果."

我没有得到这个声明.

策略侧重于拥有独立的算法,这些算法可以动态设置,并且不太了解它们所设置的客户端.

而装饰者并不完全独立于他们装饰的客户.实际上,它们与它们装饰的对象具有相同的超类型.

我在这里错过了一点吗?

design-patterns strategy-pattern

9
推荐指数
2
解决办法
5065
查看次数

战略模式应该是无国籍的吗?

必须是一个"四人帮"策略的类是完全无状态的(即没有字段)还是它可以包含不可变状态(即最终字段)?

design-patterns strategy-pattern stateless

9
推荐指数
3
解决办法
2181
查看次数

在c#中执行此通用抽象类的最佳方法是什么?

我知道我做得不对,但我也知道有办法做到这一点.我试图尽可能地通用和抽象,否则我的代码将变得非常混乱.所以我在这里使用策略模式作为GetAggregateClient()方法.

我想要一个名为AbstractAggregate的抽象类,以便它使用泛型.将使用的类型是一系列数据类,即BlogItem,ResourceItem和AskItem.这些数据类都继承自ListItem.

这就是背景信息.这里的问题是我希望GetAbstractAggregate()返回一个实现AbstractAggregate的客户端类的实例,其中包含根据传入的枚举指定的项目类型.但是,我不能返回"AbstractAggregate".编译器不会让我这样,因为AbstractAggregateFactory类不是通用的.

有没有人有最好的方法来做到这一点?

非常感谢.

public static class AggregateHelper
{
    public enum AggregateTypes { TankTruckBlog, AskTankTruck, Resources }
}

public static class AbstractAggregateFactory
{
    public static AbstractAggregate<T> GetAggregateClient(AggregateHelper.AggregateTypes type)
    {
        switch (type)
        {
            case AggregateHelper.AggregateTypes.AskTankTruck:
                return new AskTankTruckAggregate<AskItem>();
            case AggregateHelper.AggregateTypes.TankTruckBlog:
                return new TankTruckBlogAggregate<BlogItem>();
            case AggregateHelper.AggregateTypes.Resources:
                return new ResourcesAggregate<ResourceItem>();
            default:
                throw new AggregateDoesNotExistException();
        }
    }
}

public abstract class AbstractAggregate<T>
{
    public abstract List<T> GetAggregate(Guid[] resourcetypes);

    public abstract T GetSingle(string friendlyname);


}

public class AskTankTruckAggregate<T> : AbstractAggregate<T>
{
    //not implemented yet …
Run Code Online (Sandbox Code Playgroud)

c# generics refactoring abstract-class strategy-pattern

9
推荐指数
1
解决办法
5577
查看次数

访客和策略模式之间有什么区别?

我已经学会了这两种模式但却不理解这两种模式之间的差异.

我不知道场景,何时何地使用这些模式.

任何人都可以解释差异和用例吗?

java design-patterns strategy-pattern visitor-pattern

9
推荐指数
3
解决办法
3950
查看次数

试图用Java实现一种旅行者算法

我正在尝试为这种旅行者问题实施一种简单而有效的算法(但这不是"旅行推销员"):

A traveller has to visit N towns, and:
1. each trip from town X to town Y occurs once and only once
2. the origin of each trip is the destination of the previous trip
Run Code Online (Sandbox Code Playgroud)

所以,如果你有例如A,B,C镇,

A->B, B->A, A->C, **C->A, B->C**, C->B
Run Code Online (Sandbox Code Playgroud)

不是解决方案,因为你不能做C-> A然后B-> C(你需要A->B介于两者之间),而:

A->B, B->C, C->B, B->A, A->C, C->A
Run Code Online (Sandbox Code Playgroud)

是一个可接受的解决方案(每个目的地是下一次旅行的起源).

以下是Java中的插图,例如4个城镇.

ItineraryAlgorithm是提供回答问题的算法时实现的接口.该main()如果更换方法将测试你对重复算法new TooSimpleAlgo()通过new MyAlgorithm().

package algorithm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Traveller {

    private static …
Run Code Online (Sandbox Code Playgroud)

java algorithm strategy-pattern

9
推荐指数
1
解决办法
1620
查看次数