从多个类中检索集合的值,正确的方法是什么?

Retrieving values of collection from multiple classes, what's the correct way?

本文关键字:方法 是什么 检索 集合      更新时间:2023-10-16

在此之前,感谢您的阅读!

我正在开发一个C++应用程序,我想得到有关设计问题的建议。让我解释一下:

我的应用程序的主类有一些集合,但其他类最终需要从其中一个集合中获取值。像这样:

class MainClass { 
private:
   // Collections are internally implemented as QHash
   Collection<Type1> col1;
   Collection<Type2> col2;
};
class RosterUnit {
public:
   RosterUnit() {
      /* This method needs to get a specific value from col1 and
         initialize this class with that data */
   }
};
class ObjectAction {
public:
    virtual void doAction() = 0;
};
class Action1 : public ObjectAction {
public:
    void doAction() {
       // This needs a specific value from col2
    }
};
class Action2 : public ObjectAction {
public:
    void doAction() {
       // This needs a specific value from col1
    }
};

我的第一个方法是在需要时将整个集合作为参数传递,但它对于 ObjectAction 子类来说不是很好,因为我必须传递两个集合,如果我稍后创建 ObjectAction 的另一个子类并且它需要从其他集合中获取一个元素(假设 col3(,我将不得不修改每个 ObjectAction 子类的 doAction(( 签名, 我认为这不太灵活。另外,假设我有一个对话框,并希望从那里创建一个名册单位。我必须将集合传递给对话框才能创建名册单位。

接下来,我决定在 RosterUnit 和 ObjectAction 中使用指向集合的静态变量,但我对该解决方案不是很满意。我认为它不够灵活。

我一直在阅读有关设计模式的信息,我首先认为带有 get 函数的单例可能是一个不错的选择,但经过更多调查,我认为这不是适合我的情况的设计。如果我使用全局变量,那会更容易,或多或少相同,这似乎不是正确的方法。

那么,你能给一些建议吗?

谢谢!

如前所述,迭代器适用于抽象出集合的细节。但是走这条路意味着使用迭代器的对象需要知道集合中的内容。这意味着他们需要知道如何决定集合中的哪个对象他们需要,从而增加耦合。(更多详情见以下工厂段落(这是您需要考虑的事情。

另一种方法是在 MainClass 上创建访问器方法,这些方法采用某种键并从集合中返回一个对象(findObject(key((。在内部,MainClass 方法将搜索容器并返回相应的对象。但是,若要使用此方法,您需要访问 MainClass,或者通过前面提到的依赖关系注入,或者可能使其成为单例(不过,在这种情况下不建议这样做(。

根据到目前为止提供的信息,您的 ObjectAction 工厂甚至可能最好引用 MainClass,并且作为 ObjectAction 创建逻辑的一部分,调用相应的 MainClass 访问器并将结果传递到 ObjectAction 中,从而将 ObjectAction 对象与 MainClass 分离。

您可能

想使用迭代器,它们的存在正是为了从特定容器中抽象出序列。

如果你的问题是如何将迭代器传递给首先需要它们的代码,请不要屈服于使用全局变量的诱惑。如果您必须传入参数,它可能看起来更复杂,但您的代码对此更加解耦。"依赖注入"是一个很好的关键字,如果你想阅读更多关于这个主题的信息。

我还建议您查看std::function或boost::function,而不是从ObjectAction继承。函数式风格在现代C++中变得越来越普遍,而不是在Java等语言中通常的做法。

这里没有足够的信息来说明您要做什么。你让它听起来像是"在未来的某个时候,这个静态创建的操作需要留下的数据。这有什么意义?我会说要么用数据构造操作,就像你用 Future 或 Callable 一样(,要么让命令要求下一段数据,在这种情况下,你只是在实现一个工作队列。

听起来您正在尝试做类似线程池的事情。如果这些操作以任何方式相关,那么你应该在某个组合对象中实现类似模板方法模式的东西,例如 execute(( 是抽象的,并以固定的顺序调用其他一些方法,并且不能被覆盖,其他方法必须是(协议强制执行(。