策略模式可以包含对父类的引用吗?

问题描述 投票:0回答:1

我正在尝试在代码中实现策略模式,但是遇到了我所看到的示例中未涉及的内容。这就是策略需要引用父类中包含的方法的时候。

对于简单的示例(没有父引用),请使用DuckQuackBehaviour示例:

class RubberDuck extends Duck {

  public RubberDuck() {
    setQuackBehaviour(new Squeak());
  }

}

class Squeak implements QuackBehaviour {

  public String quack() {
    return "QUACK!";
  }

}

但是如果我们现在有只鸭子喜欢说自己的名字怎么办?这意味着QuackBehaviour需要某种关于鸭子本身的引用。

class PsyDuck extends Duck {

  public PsyDuck() {
    setQuackBehaviour(new SayName(this));
  }

}

class SayName implements QuackBehaviour {

  private Duck duck;

  public SayName(Duck duck) {
    this.duck = duck;
  }

  public String quack() {
    return duck.getName();
  }

}

气味对我来说像是错误的代码。这是反模式吗?它防止QuackBehaviour被非Duck对象重用。而且关于类之间的相互依赖关系,我不太满意。

我想您也可以将函数传递给PsyDuck,例如:

class PsyDuck extends Duck {

  public PsyDuck() {
    setQuackBehaviour(new SayName(() => this.getName()));
  }

}

但是,如果我们开始要求行为中包含多个字段,那么我们将必须传递许多函数参数。

或者最好让SayName作为抽象类并让PsyDuck实现具体的版本?

class PsyDuck extends Duck {

  public PsyDuck() {
    setQuackBehaviour(new PsyDuckSayName());
  }

  class PsyDuckSayName extends SayName {

    protected String getName() {
      return PsyDuck.this.getName();
    }

  }

}

abstract class SayName implements QuackBehaviour {

  public String quack() {
    return getName();
  }

  protected abstract String getName();

}

最后一种方法[[似乎最干净,但是我希望得到一些反馈和建议。

java strategy-pattern
1个回答
0
投票
我不认为这是

本身反模式。通常,您可以使用策略模式从类(或实例)外部提供“逻辑”,因此,如果以这种方式编写,则变得更加清晰(尽管直接在子类中使用也可以) :

Duck duck = new WhateverDuck(); duck.setQuackBehaviour(new SayNameBehaviour(duck)); // or: duck.setQuackBehaviour(new MeowBehaviour());
因此,对于鸭子实现而言,如何实现嘎嘎无关紧要。如果实现需要鸭子引用来执行其工作-那就这样。如果不是-很好。

[其他常用模式定义了“策略”实现所需的参数,因此您可以声明quackBehaviour例如作为Function<Duck, String>类型。实现仍可以选择忽略该参数。但这对可能的(和不可能的)实现方式做出了一些假设,应谨慎使用。就您而言,我更喜欢第一个变体。

© www.soinside.com 2019 - 2024. All rights reserved.