关于组合模式中安全方式与透明方式的疑问
大多数资料上说
透明方式:也就是说在Component中声明所有用来管理子对象的方法中,其中包括Add、Remove 等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点 和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf 类本身不具备Add()、Remove()方法的功能,所以实现它是没有意义的。
安全方式:也就是在Component接口中不去声明Add和Remove方法,那么子类的Leaf也不需要去实现它,而是在 Composite声明所有用来管理子类对象的方法。不过由于不透明,所以树叶和树枝将不具有相同的接口, 客户端的调用需要做相应的判断,带来了不便 。
其中红色部分我不是很明白,透明方式虽然接口是一致的,但是叶子节点对象没有实现Add()与remove(),在这个模式下如果我们不判断它是不是叶子就调用add()与remove方法,这不是会出问题吗,这么说来不也是避免不了要做相应的判断了吗?这怎么就成了两者的区分点了呢?请大神提点一下。
[解决办法]
只提供函数没有实现会有什么问题呢
[解决办法]
“客户端的调用需要做相应的判断,带来了不便”说的是要dynamic_cast
[解决办法]
只要把透明方式中component的Add和Remove函数默认实现为空处理就行了,子类需要才重写!
class Component{public: virtual void Add(Component *){} virtual void Remove(Component* ){}};//overwriteclass Branch : public Component{ virtual void Add(Component*) { //add branch or leaf } virtual void Remove(Component*) { //remove branch or leaf }};class Leaf : public Component{ //no child branch or leaf,don't overwrite Add and Remove fucntion};
[解决办法]
想办法通告调用者不要对Leaf做出Add,Remove的预期。(在调用者眼中叶和枝都表现为Component的形式)
或者把责任推给调用者,让他对Component做出类型判断(有多种方法),如你的资料中安全方式。
若是你想让Composite承担多些责任,可以让它管理内部结构,并暴露出遍历内部结构(可Add,Remove)的接口(Composite更多的想表达主-从,先-后等的层级顺序,虽Composite也有一些些要隐藏这个结构想法)。
[解决办法]
那再加一层Component 没有add,remove,然后现有的Component 继承新加的, 你说的哪些leaf直接继承新加的