Language agnostic 如何修改地图元素键

Language agnostic 如何修改地图元素键,language-agnostic,map,Language Agnostic,Map,我有一个容器,其中包含元素的映射 class MyContainer{ ..... Map<String,MyElement> elements = new ... ... } 我需要使用map数据结构,因为我有许多基于元素名的读取操作 问题是我需要支持修改元素的名称。更改元素名称必须派生映射中的更改。(插入具有新键的元素,否则我将无法找到该元素) 我考虑过两种选择: 将setName方法添加到MyElement类,该类将更新名称已更改的容器 不要将setName方法添加到MyEl

我有一个容器,其中包含元素的映射

class MyContainer{
.....
Map<String,MyElement> elements = new ...
...
}
我需要使用map数据结构,因为我有许多基于元素名的读取操作

问题是我需要支持修改元素的名称。更改元素名称必须派生映射中的更改。(插入具有新键的元素,否则我将无法找到该元素)

我考虑过两种选择:

  • 将setName方法添加到MyElement类,该类将更新名称已更改的容器

  • 不要将setName方法添加到MyElement类中,将rename元素方法添加到容器中,容器将负责更新映射中的元素名称和键

  • 选项1意味着我必须维护从每个元素到容器的引用。(程序的这一部分应保持较低的内存占用)


    你怎么说?您看到更好的选项了吗?

    我会在元素的setName方法上触发一个属性更改通知,并在侦听该通知的容器对象中处理它

    首先,请注意,如果
    MyElement
    可以在没有
    MyContainer
    的上下文中使用,则选项1不适用

    MyContainer
    MyElement
    有着明显的关系,因为它的代码通过映射引用了
    MyElement
    实例。反之亦然:
    MyElement
    中的代码不需要引用
    MyContainer
    。因此,选择2更好

    不过,也许你可以选择第三种混合动力:

    • MyElement
      有一个
      rename
      方法,它只更改自己的名称;
      MyContainer
      有一个
      rename
      方法,它调用
      MyElement.rename
      并将映射中的对象移动到新键

    如果该元素仅在此容器中使用

    将重命名操作放在容器上


    将元素上的重命名方法设置为私有,这样其他程序员就不会意外地只更改元素而忘记更新容器。

    选项2最简单、最有效,因此我选择它。 很明显你知道,那么难题是什么

    另一个选项是创建一个MyString类,该类将用作std::string和MyContainer的引用。MyString的修改方法将负责重新映射,而您的占用空间仍然很小。例如:

    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是单例


    另一个要考虑的事情是,名称的变化是什么时候?

    注意,这可能是一个很好的解决方案,但是它会增加元素的大小:每个事件注册将意味着元素需要保持对处理事件的目标函数的引用。
    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 */