我是否正确理解了这种策略模式?

时间:2014-06-21 05:55:34

标签: c# xna-4.0 strategy-pattern

在我之前的问题中,我被告知下面的代码是战略模式的一个例子。特别是_player.Draw(spriteBatch, _context);行。

除了前者是一个额外的方法调用之外,我没有看到该行与它下面的行之间的区别。

有人可以解释一下为什么我不会只使用_drawHugeContext的第二次调用和Draw()类中的(喘气)删除Player吗?这个例子是不是太简单了,前者会更好吗?

public class Arena
{
   Player _player;
   IPlayerContext _drawHugeContext;

   public void Draw(SpriteBatch spriteBatch)
   {
      _player.Draw(spriteBatch, _drawHugeContext);
      _drawHugeContext.Draw(spriteBatch, _player);
   }
}

public class Player
{
    public int Percentage { get; private set; }
    [...] //A few more fields

    public void Draw(SpriteBatch spriteBatch, IPlayerContext context)
    {
        context.Draw(spriteBatch, this);
    }
}

public class IPlayerContext
{
    public void Draw(SpriteBatch spriteBatch, Player player)
    {
        spriteBatch.Draw(player.Percentage);
        [...] //A few more fields drawn from player
    }
}

2 个答案:

答案 0 :(得分:0)

我不认为这是一个很好的例子。回答你的问题:

1)该示例没有显示如何选择策略。由于SpriteBatch已经预先确定。这将有助于示例更完整。

2)直接在玩家上调用抽奖会增加不必要的间接水平,并且不会立即显示出更好的位置/方式。

有很多例子,但我已经包含了一个我使用过的策略模式的例子,我在#34; C#中的设计模式中首次遇到了这种模式。作者:Steven Metsker(GoF模式的优秀C#书)。我更喜欢wiki或doFactory变体,但它们也是不错的选择。这可能有助于您理解。

假设您有一个保险套餐,它依赖于根据客户提供的报价生成'风险因素。

保险包将使用引用引擎来执行此操作。

首先,使用定义所有策略共享的战略操作的方法定义接口。

引用引擎策略的公众面孔由界面表示:

public interface IQuoteEngineStrategy
{
     decimal QuoteMeHappy(int riskDetails) 
}

并给出了2个示例具体实现

public class OnlineQuoteEngineStrategy : IQuoteEngineStrategy
{
    public decimal QuoteMeHappy(Customer c) { // online related retrieval } 
}

public class OfflineQuoteEngineStrategy : IQuoteEngineStrategy
{
   public decimal QuoteMeHappy(Customer c) { // offline related retrieval } 
}

QuoteEngine决定根据客户的事情抛出选定的策略。在这里,年龄是决定因素。

public class QuoteEngine 
{

    public static IQuoteEngineStrategy GetQuotingEngine(Customer c) 
    {
        if (c.Age < 25 )
        {
           return new OnlineQuoteEngineStrategy();
        }
        else
        {
           return new  OfflineQuoteEngineStrategy();
        }
    }

}

最后,InsurancePackage使用QuoteEngine,为QuoteEngine传递一些信息以选择其策略并调用最初识别的战略操作。

public class InsurancePackage 
{

  public decimal RiskQuote(Customer c)
  {
       return QuoteEngine.GetQuotingEngine(c).QuoteMeHappy(c);
  }
}

策略模式隐藏了消费者对特定策略的实施和选择。

它允许战略决策远离消费者。除此之外,每个具体策略都可以充当适配器来分离外部依赖。

另一个好处是可以添加额外的策略,而不需要更改InsurancePackage,这意味着QuoteEngine遵循单一责任原则(SRP)和InsurancePackage开放/封闭原则(打开扩展关闭以进行修改。(查看叔叔Bob Martin)和SOLID设计原则也是如此)

答案 1 :(得分:0)

您正在使用strategy patterns,但可能您还不知道为什么以及如何使用它们。让我举一个非常简单的例子。

假设你有一组对象,你想对它们进行排序。问题是:如何指定排序顺序?在.Net中,这通常通过传递一个lambda或一个知道如何将这两个对象与“Sort”方法进行比较的类来完成,例如

var sorted = MyObjects.Sort((a,b) => a.Id > b.Id);

这允许您将如何对列表进行一般排序的逻辑解耦为如何对特定集合中的两个元素进行排序的逻辑。

在你的情况下,SpriteBatch是在调用中注入的策略,因此你的对象结构不需要知道如何绘制东西。

我认为您可以使用上面的示例有效地重构代码。