【发布时间】:2016-03-03 10:48:47
【问题描述】:
鉴于应用程序范围内的对象集合,以及许多需要频繁访问这些对象的不相关类,提供上述访问权限的最佳方式是什么?
例子:
// Object A, stored in collections, used to do useful things
class A
{
...
public:
QString property(const QString& propertyName) {return m_properties.value(propertyName);}
protected:
QHash<QString,QString> m_properties;
}
// Collection class, contains methods to:
// - Access members of collections
// - Add/Remove members from collection
class GlobalCollection
{
public:
// Accessors to collection/collection members
static A* getAs() {return aHash;}
static QHash<QString,A*> getAByKey(const QString& key) {return aHash.value(key);}
static QList<A*> getAsMatchingCriteria(const QString& property, const QString& value)
{
QHash<A*> subsetOfA;
foreach(A* pA, aHash.values())
{
if (pA->property(property) == value)
subsetOfA << pA;
}
return subsetOfA;
}
protected:
QHash<QString,A*> aHash;
}
// Example client class that uses A's to do its job
class Client
{
public:
// This is tied to a button click, and is executed during run-time at the user's whim
void doSomethingNonTrivialWithAs()
{
// Get A* list based on criteria, e.g. "color" == "green"
QList<A*> asWeCareAbout = ???;
// Draw all the "green" A's in a circle holding hands
foreach(A* pA, asWeCareAbout)
{
// Draw a graphical representation of pA
// If pA has "shape" == "square", get a list of all the non-"green" "square" A's and draw them looking on jealously from the shadows
// Else if pA has "shape" == "circle", draw the non-"green" "circles" cheering it on
}
}
}
假设:
- 优先考虑小型、轻量级的类,因此客户端对象数量众多
- 客户端对象可能在 GlobalCollection 的“对等体”内部有好几层,而中间层不依赖于 A* 或 GlobalCollection
- 目前这是作为单例实现的
其他解决方案的设计要求和问题:
- 依赖注入看起来像是调用代码的不合理负担(考虑到分层),并且为了我的喜好牺牲了太多的清晰度
- 我不反对静态类而不是单例,但感觉并不比单例好多少
- 修改集合的代码是隔离的,所以我现在不担心
- 该解决方案需要在 GlobalCollection 和 A 中提升线程安全性(假设多个客户端最终可能在同一个 A* 上工作。)目前这是通过一个互斥锁和过度锁定来实现的,很大程度上是因为它是很难管理对 A 的访问。
- 我正在尝试迭代以实现可测试性,而当前的设计使得客户端的几乎每个测试都需要首先正确设置 GlobalCollection。
- 在生产代码中,我们有多个 GlobalCollections(用于 A、B、C 等),因此欢迎使用模板解决方案。
虽然我正在重构遗留代码来做到这一点,但我主要关心的是首先设计正确的架构。这似乎是一个非常常见的逻辑概念,但我看到的所有解决方案都未能解决将其用于生产的某些重要方面,或者存在明显的缺陷/权衡。也许我太挑剔了,但根据我的经验,适合这项工作的工具在这种情况下的缺点为零。
【问题讨论】:
标签: c++ design-patterns architecture refactoring legacy-code