我正在学习复合设计模式,当我尝试在Leaf I中添加或删除组件时,我无法理解如何对每个组件进行相同的处理(Leaf和Composite)应该得到一个错误(或什么都不应该发生)。这对我来说似乎是一种可怕的设计,因为它违反了继承规则来对待对象。唯一的方法是以某种方式区分Composite和Leaf,并始终注意我正在使用的是什么。但这让我回到原来的问题......
组件:
public abstract class Equipment {
private String name;
protected Equipment(String name){
this.name = name;
}
public String name(){
return name;
}
public abstract int power();
public abstract double netPrice();
public abstract double discountPrice();
public abstract void add(Equipment equipment);
public abstract void remove(Equipment equipment);
public Iterable<Equipment> createIterator(){
return Collections.emptyList();
}
}
组合:
public abstract class CompositeEquipment extends Equipment{
private final List<Equipment> elements;
protected CompositeEquipment(String name) {
super(name);
elements = new LinkedList<>();
}
@Override
public double netPrice() {
Iterable<Equipment> iter = createIterator();
double total = 0;
for (Iterator<Equipment> i = iter.iterator(); i.hasNext() ;) {
Equipment next = i.next();
total += next.netPrice();
}
return total;
}
@Override
public Iterable<Equipment> createIterator() {
return elements;
}
@Override
public void remove(Equipment equipment){
elements.remove(equipment);
}
@Override
public void add(Equipment equipment){
elements.add(equipment);
}
}
叶
public class FloppyDisk extends Equipment{
public FloppyDisk(String name) {
super(name);
}
@Override
public int power() {
return 1;
}
@Override
public double netPrice() {
return 3;
}
@Override
public double discountPrice() {
return 2.2;
}
@Override
public void add(Equipment equipment) {
//we well do nothing here because thats the final element of the tree
}
@Override
public void remove(Equipment equipment) {
//we well do nothing here because thats the final element of the tree
}
}
我看到的问题:
public void extendTheTree(Equipment equipment){
equipment.add( new CompositeWithLeafs() ); //lets hope it is a Composite not a Leaf!!!
}
那么我应该如何使用这种模式呢?或者在什么样的场景中?我看到的唯一解决方案是摆脱Leaf概念并仅使用Composits。
答案 0 :(得分:2)
你误解的根源在于你采用了对Leaf有意义的方法和对Composite有意义的方法,并将这些方法的联合放在public abstract class Equipment
中,即你的组件。这样,你最终得到了Leaf和Composite的共同祖先,其中一部分祖先对Leaf没有意义。我说的是add
和remove
方法,它们对Leaf没有意义,因此首先不应该成为Component的一部分。是否应该使用抽象类或接口来表示组件是另一个问题,您可以在此站点中找到完美的分析。但事实是Component应该包含Leaf的方法和Composite的方法的交集,这是一组可以在对象上使用的方法,而不知道它是Leaf还是Composite。更正式地说,Component应该定义应该由Leaf和Composite实现的公共接口。如果你这样做,你会发现你永远不会add
到Leaf,因为Component接口不应该有这样的方法来覆盖,而Leaf也不应该有这样的方法。无论好坏,你只能add
到你认识的是复合材料。