代码之家  ›  专栏  ›  技术社区  ›  FrenchData

在策略模式中,策略能否以上下文为参数

  •  10
  • FrenchData  · 技术社区  · 15 年前

    反馈摘要

    现在我将结束这个主题(我想不会有更多的反馈),并尝试总结我所理解的内容

    1. 为了最大限度地减少耦合,最好提供所需的值,或者至少使用接口,而不是策略的具体类型。

    让我们来看下面的经典实现

    //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();
      }
    }
    

    我所看到的所有例子都有非常简单的策略,这些策略采用基本参数(例如整数)。我想知道的是,如果策略使用上下文来完成工作,是否存在错误。

    它会给你类似的东西

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

    而这一召唤将给予

    //The context
    class Context
    {
      ....
    
      public void Execute()
      {
        strategy.Execute(this);
      }
    }
    

    是否要避免这种“耦合”?可以吗?

    3 回复  |  直到 15 年前
        1
  •  7
  •   sateesh    15 年前

    我认为你的方法有一个问题,那就是混凝土之间会有一个紧密的耦合 上下文 类和策略类的实例。这意味着策略类只能与上下文类一起使用。避免这种情况的一种方法是使策略类依赖(或使用)一个“上下文”类将实现的接口。

    编辑 此外,当策略类具有上下文类的实例时,这些类必须从上下文类显式地获取数据。这意味着在上下文类中为策略类添加getter(根据需要),以获取它们所需的数据。但是添加getter并不一定是一个好的OO实践,因为更多的getter会带来破坏封装的风险。

    你能想到的另一个选择是 将上下文类的引用传递给strategy类中的方法,但只将所需的数据传递给strategy类。

    例如,如果上下文类是这样的:(代码是Java)

    Context {
       IStrategy strategy;
       List<Integer> scores;
    
       public Context(IStrategy strategy)
       {
            this.strategy = strategy;
            scores = new ArrayList<Integer>
       }
    
       public print() {
           strategy.sort(scores);
       }
    }
    
    public interface IStrategy<Integer> {
        public void sort(List<Integer> l);
    }
    

    在上面的代码中,Strategy类在一个通用整数列表上操作,并且不特别绑定到上下文类中。 此外,还可以在定义Strategy类时使用泛型方法,以便 分类 方法不仅适用于整数,还适用于泛型类型。

        2
  •  5
  •   Benny    15 年前

    嗯,没关系。但我更喜欢通过strategy实现类的构造函数将上下文传递给策略。

        3
  •  2
  •   Ed Gonzalez    15 年前

    你的代码就是你的代码,写任何对你有意义的东西。不过,我有一句忠告。

    战略模式的目的是创建一系列可以互换的战略。与许多设计模式一样,它也从解耦中获益。在本例中,我们将行为与使用此类行为的类分离。

    当一个策略将上下文作为一个参数时,解耦就减少了。上下文中的更改可能需要更改您的战略实施。正如前面的一张海报所指出的,最好是寻找一种使它们解耦的方法。

    也就是说,只要您的目的是允许策略可互换,并且您的代码实现了这个目的,那么我看不出有什么问题。

        4
  •  0
  •   celsowm    4 年前

    ,有几种方法,包括您的:

    enter image description here