假设你有一个大约 30 个类的 Java 类层次结构,有一个基类 BaseClass 和两个主要子类(SubclassA、SubclassB),每个子类有几个子类。 其中一些子类具有一定的行为。 假设您可以"戳"它们,改变它们的状态。 (这是一项将行为添加到现有层次结构的新要求。 "戳"对大多数班级来说毫无意义。
interface Pokeable {
void poke();
int getTimesPoked();
}
public class Pokey extends SubclassB
implements Pokeable {
private int timesPoked = 0;
public void poke() {
timesPoked++;
}
public int getTimesPoked() {
return timesPoked;
}
}
这是否应该通过在那些需要它的类中实现 Pokeable 来完成,然后在必须戳任何可戳的对象的所有代码中执行以下操作?
public void process(BaseClass b) {
if (b instanceof Pokeable) {
((Pokeable)b).poke();
}
}
还是整个层次结构应该为了少数真正可Pokeable的人而实现Pokeable?
interface Pokeable {
void poke();
int getTimesPoked();
boolean isReallyPokeable();
}
public class BaseClass implements Pokeable {
public void poke() {}
public int getTimesPoked() { return 0; }
public boolean isReallyPokeable() { return false;}
}
public class Pokey {
private int timesPoked = 0;
@Override
public void poke() {
timesPoked++;
}
@Override
public int getTimesPoked() {
return timesPoked;
}
@Override
public boolean isReallyPokeable() {
return true;
}
}
public void process(BaseClass b) {
b.poke();
}
编辑添加:这是一种双重调度问题。 当"扑克"代码对对象执行某些操作时,如果对象是"可戳的",则必须调用"poke()",但如果不是,则不能。 你是否"poke()"取决于某物是否想要戳以及对象是否接受被戳。 我可以使用访客模式,但这似乎使它更加复杂。
如果一个类不可戳,我建议不要让它实现Pokeable
接口,因为这会令人困惑。
请改为采用以下方法之一。
- 创建一个实现
Pokable
的抽象或具体的BaseClass
子类,并让所有即将Pokeable
的子类扩展它。 如果poke()
ing 是通过所有实现类中的相同逻辑实现的,则此方法非常有效。 - 让每个子类单独实现
Pokeable
使用一种名为"isReallyX"的方法是一个警告信号。 如果有人一目了然地查看一个类并看到它是"可戳的",他们可能会尝试戳它并最终出现意外的行为,因为它不是真正可戳的。
我会采取你以前的方法,它不会误导外部程序员(或者在忽略这段代码两个月后你自己!
如果您不想实现父类的所有方法,则子类可能是抽象的。 但是....
还是应该整个层次结构为了实现Pokeable,以便 很少有真正可以戳的?
绝对不...不可戳的类不应实现可戳的接口。
这是否应该通过在那些类中实现 Pokeable 来完成 需要它,然后在必须戳的所有代码中执行以下操作 有什么可以戳的物体吗?
这是一个稍微好一点的模型...但是,这是一个非常程序化的设计。
还可以将<Pokeable>
物品的集合放在一边的某个地方,然后快速迭代该集合以将它们全部戳掉?
你能让可戳的类向事件调度员注册吗?那么当某个事件发生时,所有的班级都被戳了?