【问题标题】:How to remove the circular dependency from this use of the Strategy pattern?如何从策略模式的这种使用中移除循环依赖?
【发布时间】:2016-07-27 14:30:29
【问题描述】:

我正在尝试理解策略模式并想出了以下示例:

  • 我想创建基于国际象棋的新游戏,但棋子的移动方式不同。
  • 我还想使用策略模式将行为(它们如何移动)注入到各个部分中。

但如果我们有 BoardPieceMoveBehavior 对象

  • Board -> Piece 因为Board 包含Pieces
  • Piece -> Board 因为一块需要传入Board 作为参数
    • MoveBehavior 需要 Board 来决定哪些动作是可以接受的。

我们怎样才能摆脱这种循环依赖?此外,这不是更现实的例子中的常见问题,因为行为需要足够大的状态来做出决定吗?我认为如果行为超级简单,不使用策略模式也没什么大不了的。

【问题讨论】:

    标签: design-patterns strategy-pattern


    【解决方案1】:

    听起来您可以使用依赖注入框架来解析所有对象实例。如果您想使用不同的类型组合来实例化,您将需要一个可配置的容器。您可以将可配置容器称为策略(因为它选择了所有起作用的部分)。

    我不会让开发板负责创建所有的片段和行为,而是为此使用一个作曲家类(使用依赖注入)。

    这允许您(例如)为板子使用行为,或者也可以创建不同的板子类型。

    另请参阅this question and answer,了解依赖注入如何帮助获得松散耦合的一些背景知识。

    【讨论】:

      【解决方案2】:

      我只会使用Board -> Piece -> MoveBehaviour

      原因是棋盘包含棋子,棋子有自己的移动行为,具体取决于它们的类型。

      MoveBehaviour 告诉作品它允许的运动,即(例如 C#,因为这是我所熟悉的)

      public Move[] Moves
      {
          get
          {
              return new Move[] { Move.Horizontal, Move.Vertical };
          }
      }
      

      MoveBehaviour 的工作不是查看Piece 是否可以移动到它所请求的位置。

      在下面的 C# 示例中更容易解释:

      public class Board
      {
          public List<Piece> Pieces { get; set; }
      
          public bool CanMoveTo(Piece piece, Point location) { /*...*/ }
      }
      
      public class Piece : IMoveBehaviour
      {
          public Move[] Moves { get; set; }
      }
      
      public interface IMoveBehaviour
      {
          Move[] moves { get; set; }
      }
      

      使用BoardPiece 中的方法,例如RequestMoveMoveIsValidMove 等...

      基本上将某事的责任留给某事,而不是移动它。 MoveBehaviourPiece 的行为,而不是 Boards 职责的移动验证。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-05
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多