1

我的情况理论上可能非常适合复合和迭代器设计模式,但我对这些模式的问题是无法访问可能成为交易破坏者的底层数据结构。

当然,我可以在一个国家的一个城市的商场里开一家商店,这建立了整体关系,如果我制作它的复合模式,我可以对所有对象(大部分)运行通用方法,比如商店/商场的时间打开和关闭,但实际上我们需要的不止这些。

以一个简单的任务为例,将这种复合结构从已保存的文件加载到树控件中。现在我们甚至都不知道哪个组件是什么,所以我们甚至无法确定一个组件应该是树中的父级、兄弟级还是子级。我们本质上必须进行某种类型检查,以找出首先反对哪种复合模式。对于外部迭代器尤其如此。

起初,这两种模式组合起来似乎有更大的潜力,但现在它们似乎没什么用。

我试图找到这两种模式的真正理由。Print() cost()除了简单的教科书示例(如函数)之外,它在哪里最好用。当从文件加载复合材料时,必须将复合材料进行类型转换以填充树控件以反映复合材料的层次结构,我对吗?

4

2 回答 2

4

你不需要迭代器,你需要一个访问者

迭代器用于统一的对象;你的对象绝对统一。此外,当以统一的方式使用对象时,复合往往会更好地工作。一个经典的例子是你计算的表达式;另一个是您在屏幕上渲染的几何图形。同样,您的案例不适合经典的复合模式,因为商店和县没有太多共同点。

幸运的是,visitor 解决了所有问题:定义一个知道如何处理城市、县、商场和商店的访问者类。使这些类中的每一个都“可访问”,并将它们安排在一个组合中。现在,您的类在组合中的统一属性是每个类都可以被访问。叶类将回调访问者,并将自己作为参数传递。分支类将首先传递自己,然后将访问者传递给它们的所有组件。这将使您以一种简洁明了的方式遍历整个层次结构。

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);
    }
};
于 2013-10-18T21:19:53.167 回答
0

一个符合 stl 的复合外部迭代器的示例,请参阅github 上的这个复合迭代器存储库。它是一个前向迭代器。*iter 返回基类 Node。该组合是来自 Pattern Hatching 的文件系统示例。见第 其中 25张幻灯片用于描述和类图。目录是复合的。叶节点是 File 实例,两者的基组件类是 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;
}
于 2014-01-01T00:58:39.220 回答