在此之前,感谢阅读!
我正在用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()签名,我认为这不太灵活。另外,假设我有一个Dialog并想从那里创建一个RosterUnit。我必须将集合传递给对话框才能创建RosterUnit。
接下来我决定在RosterUnit和ObjectAction中使用指向集合的静态变量,但我对这个解决方案并不满意。我认为它不够灵活。
我一直在阅读有关设计模式的内容,我首先想到一个带有get函数的Singleton可能是一个不错的选择,但经过一些更多的调查后我认为这不适合我的设计。如果我使用全局变量会更容易,或多或少相同,这似乎不是正确的方法。
那么,你能提出一些建议吗?
非常感谢!
答案 0 :(得分:0)
您可能希望使用迭代器,它们的存在完全是为了从特定容器中抽象出序列。
如果您的问题是如何将迭代器传递给首先需要它们的代码,请不要屈服于使用全局变量的诱惑。如果你必须传入参数,它可能看起来更复杂,但你的代码更加分离。如果您想要阅读有关此主题的更多信息,“依赖注入”是一个很好的关键字。
我还建议您查看std :: function或boost :: function,而不是从ObjectAction继承。功能风格在现代C ++中变得越来越普遍,而不像通常在Java等语言中完成。
答案 1 :(得分:0)
这里没有足够的信息说明你要做什么。你可以在未来的某个时候听到它,这个静态创建的动作需要留下的这些数据。&#39;这有什么用呢?我会说用数据构造动作,就像你使用Future或Callable一样构建动作,或者让命令询问下一条数据,在这种情况下你只是实现一个工作队列。
听起来你正在尝试做类似线程池的事情。如果这些操作以任何方式相关,那么您应该在某个组合对象中实现类似模板方法模式的操作,例如execute()是抽象的,并且以固定的顺序调用其他一些方法并且不能被覆盖,其他方法必须是(协议实施)。
答案 2 :(得分:0)
如前所述,迭代器有助于抽象出Collection的细节。但是走这条路线意味着使用迭代器的对象需要知道Collection内部的内容。这意味着他们需要知道如何确定他们需要的Collection中的哪个对象,从而增加耦合。 (以下工厂段落的详细信息)这是您需要考虑的事项。
另一种方法是在MainClass上创建访问器方法,它采用某种键并从Collection(findObject(key))返回一个对象。在内部,MainClass方法将搜索容器并返回适当的对象。要使用这种方法,您需要访问MainClass,可以通过前面提到的依赖注入,也可以使它成为Singleton(不过在这种情况下不推荐)。
使用到目前为止提供的信息,您的ObjectAction Factory甚至可能更好地引用MainClass,并且作为ObjectAction创建逻辑的一部分,调用相应的MainClass访问器并将结果传递给ObjectAction,从而将ObjectAction对象与MainClass分离。