java - 策略模式可以包含对父类的引用吗?
问题描述
我正在尝试在我的代码中实现策略模式,但我遇到了我见过的示例中未涵盖的内容。这就是策略需要引用父类中包含的方法的时候。
对于简单的示例(没有父引用),让我们使用Duck
andQuackBehaviour
示例:
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();
}
最后一种方法似乎最干净,但我希望得到一些反馈和建议。
解决方案
我不认为它本身是一种反模式。通常,您使用策略模式从类(或者更确切地说,一个实例)外部提供“逻辑”,因此如果您这样编写它会变得更清晰一些(尽管直接在您的子类中使用它也可以) :
Duck duck = new WhateverDuck();
duck.setQuackBehaviour(new SayNameBehaviour(duck));
// or:
duck.setQuackBehaviour(new MeowBehaviour());
因此,如何实现 quack 对鸭子实现无关紧要。如果实现需要鸭子引用来执行其工作 - 就这样吧。如果没有 - 很好。
其他常用模式定义了“策略”实现所期望的参数,因此您可以将您的quackBehaviour
eg 声明为 type Function<Duck, String>
。实现仍然可以选择忽略该参数。但这对可能(和不可能)的实现做出了一些假设,应该谨慎使用。在您的情况下,我更喜欢第一个变体。
推荐阅读
- php - 单个 WP_Query 可以从 X 标签获取帖子,但如果没有结果,则回退到 X 类别
- c++ - 什么时候可以安全地释放我传递给 DirectX 的内存?
- ios - 如何输出 iOS 发布二进制文件的函数列表
- r - iGraph for R 中的 stmincuts 问题
- amazon-eks - 如何更改每个节点的默认 Pod 数量?
- sonarqube - SonarQube Scannner 执行期间出错
- javascript - 角度 tslint 设置错误。ng build:成功,ng build --prod:失败
- xml - XSLT 1.0 Kludge 清理
- python-3.x - 如何通过套接字发送消息序列?
- swift - 我如何正确编写 if - else if 代码