创建深层嵌套的对象进行修改是否是一种好习惯?

时间:2019-05-30 00:01:45

标签: javascript design-patterns javascript-objects

为了学习Javascript,我正在构建一个简单的浏览器游戏。我在游戏中具有以下层次结构中的某些对象:

  • 位置
    • 位置...
      • 元素
        • 互动
      • ...
    • 元素
      • 互动
        • 物品
      • 其他信息(例如统计信息)

基本上,每个位置都有一个父位置,可能还有一个子位置。每个位置都有元素,这些元素具有交互作用,其中包含项目以及其他标识符对象。

每个位置,元素和互动都是唯一的,并且只能有一个父元素(例如,元素10仅在一个位置的子元素中)。项目和标识符对象可以有多个父对象。 然后,我构建游戏,并用JSON对数据进行字符串化处理,并且仅在出现提示时在Web应用程序中进行重建。

在构建过程中,我认为可以花费更长的时间,但是我想在游戏过程中优化速度和内存。

存储分层关系的最佳实践是什么?

当前,我正在执行以下操作: 每个位置都有其父级,子级和元素的唯一位置ID。 每个元素都有父位置ID,交互ID和其他标识符。 每个交互都有其父元素id和项目的id(如果适用)。 每个项目和标识符对象都没有父母或孩子。 然后,游戏构建是以下内容的地图:

位置:每个位置ID到数据的映射

元素:每个元素ID到数据的映射

互动:每个互动ID到数据的映射

Item:每个itemId到数据的映射。

标识符对象:从每个标识符ID映射到数据

在某些伪代码中,这是:

let _LocNames = {};
function _Location(locationId, parentId, context) {
    this.locationId = locationId;
    this.parentId = parentId;
    this.children = []; // array of strings
    this.elements = []; // array of strings
    // ... other stuff
    _LocNames[locationId] = this;
}

_Location.prototype.addChild = function(childId) {
    new _Location(childId, this.locationId, context);
    this.children.push(childId);
};

_Location.prototype.addElement = function(elementId) {
    this.elements.push(elementId);
};

let _ElementNames = {};
function _Element(elementId, parentId, context) {
    this.elementId = elementId;
    this.parentId = parentId;
    this.interactions = []; // array of strings
    // ... other stuff
    _LocNames[parentId].addElement(elementId);
    _ElementNames[elementId] = this;
}

_ElementNames.prototype.addInteraction = function(interactionId) {
    this.interactions.push(interactionId)
}

let _InteractionNames = {};
function _Interaction(interactionId, elementId, context) {
    this.interactionId = interactionId;
    this.elementId = elementId;
    this.items = context.items; // array of itemIds (strings)
    // ... other stuff
    _ElementNames[elementId].addInteraction(interactionId);
    _InteractionNames[interactionId] = this;
}

let _ItemNames = {};
function _Item(itemId, context) {
    this.itemId = itemId;
    // ... other stuff
    _ItemNames[itemId] = this;
}

let Data = {};
Data["Location"] = _LocNames;
Data["Element"] = _ElementNames;
// so on so forth

// The game build would then be
JSON.stringify(Data)

然后,假设我想对某个位置的所有元素进行操作:

Data.Loc[locId].elements.map(elementId => foo(Data.Element[elementId]))

这很好,但是是否可以使用更好的设计模式来嵌套更深的层次结构?例如:

function _Location(locationId, parent, context) {
    this.locationId = locationId;
    this.parentId = parent;
    this.children = {};
    this.elements = {};
}

let _baseLocation = new _Location("BASE", null, null);

function _findParent(id) {
    // Do something starting at the root node (_baseLocation)
    // and find the parent using some kind naming / design.
    return parent; // Note: the object, not the parentId
}

addChild(childId, context) {
    let parent = _findParent(childId);
    parent.children[childId] = new _Location(childId, parent, context);
}

function _Element(elementId, parent, context) {
    this.elementId = elementId;
    this.parent = parent;
    this.interactions = {};
}

addElement(elementId, context) {
    let parent = _findParent(elementId);
    parent.elements[elementId] = new _Element(elementId, parent, context);
}

// so on for the others lower on the hierarchy. 
// Then the game build would look like
JSON.stringify(_baseLocation)

然后在游戏过程中,由于不可能在层次结构中跳到一个以上的级别,因此,如果我们返回上一级,我们可以直接转到父级。

在第一个设计中,最深的对象是(数据->对象类型->对象名-> ifArray / Map->仅字符串/数字)中的4,而在第二个设计中,它可能真的很深。

似乎是存储名称,并进行更浅层的设计更有益和有用。如果是这样,那么是否也适用于非常大的数据集?

0 个答案:

没有答案