查找和可能更改方法的最佳设计
时间:2020-03-06 14:39:32 来源:igfitidea点击:
我正在设计一个用于存储(缓存)一组数据的类。我想查找一个值,如果类包含该值,则使用它并修改该类的属性。我担心公共接口的设计。
这是将如何使用该类的方法:
ClassItem *pClassItem = myClass.Lookup(value);
if (pClassItem)
{ // item is found in class so modify and use it
pClassItem->SetAttribute(something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
但是我不想将ClassItem暴露给此客户端(ClassItem是MyClass的实现细节)。
为了解决这个问题,可以考虑以下内容:
bool found = myClass.Lookup(value);
if (found)
{ // item is found in class so modify and use it
myClass.ModifyAttribute(value, something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
但是,这样做效率低下,因为"修改"将不得不再次进行查找。这将建议使用lookupAndModify方法类型:
bool found = myClass.LookupAndModify(value, something);
if (found)
{ // item is found in class
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
但是将LookupAndModify合并为一种方法似乎是非常糟糕的设计。它也只会修改是否找到了值,因此名称不仅麻烦,而且还会引起误解。
是否有另一个更好的设计可以解决此问题?为此有任何设计模式(我无法通过Google找到任何东西)?
解决方案
假设我们在Modify和Add情况下都将值设置为相同的"内容":
if (!myClass.AddIfNotExists(value, something)) {
// use myClass
}
否则:
if (myClass.TryModify(value, something)) {
// use myClass
} else {
myClass.Add(value, otherSomething);
}
两件事情。
第一个解决方案即将结束。
但是,不要返回ClassItem *。返回一个"不透明对象"。对客户端不透明(无意义)但可由myClass实例使用的整数索引或者其他哈希码。
然后查找返回一个索引,该索引随后可以使用。
void *index = myClass.lookup( value );
if( index ) {
myClass.modify( index, value );
}
else {
myClass.add( value );
}
编写"原始"查找,修改和添加后,然后编写围绕这些原始构造的自己的复合操作。
编写一个LookupAndModify,TryModify,AddIfNotExists以及从下层代码构建的其他方法。
实际上std :: set <> :: insert()正是这样做的。如果该值存在,则返回指向现有项目的迭代器。否则,返回进行插入的迭代器。
无论如何,我们可能都在使用类似的数据结构进行快速查找,因此一个干净的公共接口(呼叫站点)将是:
myClass.SetAttribute(value, something)
总是做正确的事。 MyClass处理内部管道,客户不必担心该值是否存在。

