我有一个容纳元素图的容器。
class MyContainer{
.....
Map<String,MyElement> elements = new ...
...
}
每个元素都有name属性。地图中的关键是元素的名称。即方法插入如下:
void addElement(MyElement elem){
elements.put(elem.getName,elem);
}
我需要使用地图数据结构,因为我有许多基于元素名称的读取操作。
问题是我需要支持修改元素的名称。更改元素名称必须导出地图中的更改。 (使用新密钥插入元素,否则我将无法找到该元素)
我考虑过两个选择:
将setName方法添加到MyElement类,该类将更新其名称已更改的容器。
不要将setName方法添加到MyElement类,将重命名元素方法添加到容器中,容器将负责更新地图中的元素名称和键。
选项1意味着我必须保持从每个元素到容器的引用。 (程序的这一部分应保持较低的内存占用)。
你怎么说?你看到更好的选择吗?
答案 0 :(得分:1)
我会在元素的setName方法上触发属性更改通知,并在侦听该通知的容器对象中处理它。
答案 1 :(得分:1)
首先请注意,如果MyElement
可以设想在没有MyContainer
的情境中使用,那么选项1就可以了。
MyContainer
与MyElement
有明显的关系,因为它的代码通过其地图引用了MyElement
个实例。反之则不然:MyElement
中的代码不需要引用MyContainer
。所以选项2更好。
但也许你可以选择第三种混合选择:
MyElement
有rename
方法,只更改自己的名称,MyContainer
有rename
方法调用MyElement.rename
并移动对象映射到新密钥。答案 2 :(得分:0)
如果元素仅用于此容器中。
将重命名操作放在容器上。
将元素上的重命名方法设为私有,这样另一个程序员就不会意外更改元素而忘记更新容器。
答案 3 :(得分:0)
选项2是最简单和最有效的,因此我的选择。 显然你知道,那么什么是dillema?
另一种选择是创建一个MyString类,它既可以作为std :: string,也可以作为对MyContainer的引用。 MyString的修改方法将负责重新编写,并且你的占用空间仍然很小。 E.g:
class MyString;
class MyElement {
...
MyString name;
...
};
MyContainer * aContainer = new MyContainer;
new MyElement(MyString("Yaron Cohen",aContainer), ...); /* MyString need to be explicit only upon MyElement construction. takes care of inserting into container. */
...
MyElement * someElement = aContainer["Yaron Cohen"]; /* just std::string for lookup */
someElement->name = "Dana International": /* MyString takes care of remapping */
请注意,此选项也支持多个键和容器,例如FirstName,LastName(如果只有这些是唯一的......)
另一个选择是MyContainer是单身。
需要考虑的另一件事是,名称有多久会改变?