未能在复合/迭代器设计模式中看到真正的价值
Failing to see real value in Composite/Iterator design pattern
理论上我的情况可能非常适合复合和迭代器设计模式,但我对这些模式的问题是无法访问底层数据结构,这可能是一个交易破坏者。
当然,我可以在一个国家/地区的城市中的购物中心中开设一家商店,这构成了整体关系,如果我制作它的复合模式,我可以在所有对象上运行通用方法(在大多数情况下),例如商店/购物中心何时开放和关闭,但实际上我们需要的不止于此。
以一个简单的任务为例,将这种复合结构从已保存的文件加载到树控件中。现在我们甚至不知道哪个组件是什么,所以我们甚至无法确定一个组件应该是树中的父组件、兄弟组件还是子组件。我们基本上必须进行某种类型检查,以找出首先反对哪种复合模式。对于外部迭代器尤其如此。
起初,这两种模式的组合似乎具有更大的潜力,但现在它们似乎没有什么用处。
我试图为这两种模式找到真正的理由。除了简单的教科书示例(如Print()
cost()
函数)之外,在哪里可以最好地使用它。我是否正确,必须将复合类型转换回来以填充树控件以反映从文件加载复合时的层次结构?
迭代器,你需要一个访问者。
迭代器用于统一的对象;你的对象绝对不是统一的。此外,当以统一的方式使用对象时,复合往往效果更好。一个典型的示例是您计算的表达式;另一个是您在屏幕上渲染的几何图形。同样,您的情况不适合经典的复合模式,因为商店和县没有太多共同点。
幸运的是,访客解决了这一切:定义一个知道如何处理城市、县、商场和商店的访客类。使这些类中的每一个都"可访问",并将它们排列成复合。现在,复合类的统一属性是可以访问每个类。叶类将回调访问者,并将自身作为参数传递。分支类将首先传递自身,然后将访问者传递给其所有组件。这将使您能够以一种漂亮而干净的方式遍历整个层次结构。
class County;
class City;
class Mall;
class Shop;
struct ShoppingVisitor {
virtual void visitCounty(const County& county);
virtual void visitCity(const City& city);
virtual void visitMall(const Mall& mall);
virtual void visitShop(const Shop& shop);
};
struct ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const;
};
class County : public ShoppingVisitable {
vector<ShoppingVisitable*> children;
public:
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitCounty(*this);
for (int i = 0; i != children.size() ; i++) {
children[i]->accept(visitor);
}
}
};
class City : public ShoppingVisitable {
vector<ShoppingVisitable*> children;
public:
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitCity(*this);
for (int i = 0; i != children.size() ; i++) {
children[i]->accept(visitor);
}
}
};
struct Mall : public ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitMall(*this);
}
};
struct Shop : public ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitShop(*this);
}
};
复合的 stl 兼容外部迭代器的示例,请参阅 github 上的这个复合迭代器存储库。它是一个前向迭代器。*iter 返回基类 Node。复合是图案剖面线中的文件系统示例。有关说明和类图,请参阅这些幻灯片的第 25 页。目录是复合的。叶节点是文件实例,两者的基本组件类是 Node。例
Directory::iterator iter_current = top.begin();
Directory::iterator iter_end = top.end();
for (;iter_current != iter_end; ++iter_current) {
Node &node = *iter_current;
cout << "[address: " << hex << &node << "] " << node.getName();
if (dynamic_cast<Directory*>(&node) ) {
cout << " is a Directory ";
} else {
cout << " is a File ";
}
cout << endl;
}
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 未能在复合/迭代器设计模式中看到真正的价值
- GOF复合设计模式CompositeObject::删除C++中的递归实现