我有一个类似复合的模式,其中树木,树枝和树叶的根部有不同的功能。问题是Root with Branch和Branch with Leaf之间存在共享状态。我正在寻找防止代码重复的最干净的解决方案。
root,branch和leaf之间的功能都与同一组方法有关(虽然leaf有不同的签名)。
Branch 和 Leaf 的实现相同的问题,并且实现它会导致重复的代码。将 Embeddable 作为一个抽象类是不可能的,因为 Branch 已经扩展了 Composite 。
我正在搜索模式或常规解决方案,以便 Branch 可以同时与 Embeddable 和 Composite 共享状态。基本上是一个多继承的解决方法。
此设计实际上用于构建3D块环境。根在空间中是无限的,分支是在其父级空间中具有偏移的子部分,并且叶子表示相对于其父偏移的1个块。因此,根和分支的一些功能需要坐标作为参数,而叶子不需要那些,因为它已经在1坐标处。
public abstract class Container{
private List<Embeddable> children;
private WeakHashMap<Integer, Leaf> leafs;
public abstract boolean setBlock(short x, short y, short z, byte id, byte data, SetBlockStrategy setBlockStrategy);
public abstract void tick();
public abstract void activate(short x, short y, short z);
protected final Leaf getLeaf(short x, short y, short z) { ... }
protected void addChild(short x, short y, short z, Embeddable child) { ... }
}
public interface Embeddable {
void setParent(Container parent, short x, short y, short z);
void clearParent();
Container getParent();
}
public class Root extends Composite {
private RootSpecificObject rootSpecificParameter;
public boolean setBlock(short x, short y, short z, byte id, byte data, SetBlockStrategy setBlockStrategy) {
controller.doStuff();
}
public void tick() {
controller.doStuff();
}
public void activate(short x, short y, short z) {
controller.doStuff();
}
}
public class Branch extends Composite implements Embeddable {
private BranchSpecificObject branchSpecificParameter;
// Duplicate code
private short xOffset, yOffset, zOffset;
private Container parent;
public boolean setBlock(short x, short y, short z, byte id, byte data, SetBlockStrategy sbs) {
parent.setBlock(x + xOffset, y + yOffset, z + zOffset, id, data, sbs);
}
public void tick() {
controller.doStuff(xOffset, yOffset, zOffset, ...);
}
public void activate(short x, short y, short z) {
parent.activate(x + xOffset, y + yOffset, z + zOffset);
}
// Duplicate Embeddable implementation
}
public class Leaf implements Embeddable {
private byte id, data;
// Duplicate code
private short xOffset, yOffset, zOffset;
private Container parent;
public boolean setBlock(byte id, byte data, SetBlockStrategy sbs) {
return parent.setBlock(xOffset, yOffset, zOffset, id, data, sbs);
}
public void activate(short x, short y, short z) {
parent.activate(xOffset, yOffset, zOffset, id, data, sbs);
}
// Duplicate Embeddable implementation
}
答案 0 :(得分:2)
不清楚确切的代码是重复的,但这种问题的常见方法是将状态和行为委托给另一个类。
请记住,在可读性和维护此类代码的容易性之间总是需要权衡。现在请三思,确实需要避免代码重复。
代码的简短示例
var foo = entry[i].getElementsByTagName("url")[0].childNodes[0] || 'baar'