我正在考虑简单的问题。我给了一个例如Model
class Model {
constructor(parameters = {}) {
this.id = parameters.id;
}
}
您可以看到我们可以创建新的Model
对象,例如:let model = new Model()
。更复杂的例子如下所示:
//we have some data given from API maybe?
let parameters = {id: 1};
let model = new Model(parameters );
在这里,我开始徘徊如果给定id
的对象已经存在怎么办?
问题是我应该使用什么模式来实例化给定id
一次的对象?
让我们进一步说明:如果我们将使用循环引用获取嵌套对象,该怎么办?假设我们有另一个名为AnotherModel
的类,我们的代码如下:
class Model {
constructor(parameters = {}) {
this.id = parameters.id;
this.anotherModel= nulld;
if (parameters.anotherModel) {
this.anotherModel= parameters.anotherModel instanceof AnotherModel
? parameters.anotherModel
: new AnotherModel(parameters.anotherModel);
}
}
}
class AnotherModel {
constructor(parameters = {}) {
this.id = parameters.id;
this.models = [];
if (parameters.models) {
for (let i = 0; i < parameters.models.length; i++) {
let model = parameters.models[i];
model.anotherModel= this;
this.models.push(new Model(model));
}
}
}
}
因此AnotherModel
包含Model
s和Model
对象的集合,其中包含对AnotherModel
的引用。
解决此问题的好方法是什么?我们想要实现的是只有一个具有相同id的对象。
我在想的是做一些ObjectPool,我将存储给定类或类的所有对象,当实例化新对象时,如果不存在或者返回现有对象,我们的池会创建一个新对象吗? / p>
但是这里有一些不足之处,例如我们已经编写了一些我们必须重构的代码并改变了它们从new Model()
到ObjectPool.get(Model, parameters)
的实例化方式?
你有什么想法?
答案 0 :(得分:3)
您可以使用对象池(在类或其外部)来跟踪您的实例。通过在构造函数中定义它,您仍然可以使用:
实例化模型new Model();
new AnotherModel();
如果池中已存在id
,则只需返回现有实例。
课外:
const modelPool = {};
class Model {
constructor(parameters = {}) {
if (modelPool[parameters.id] instanceof Model) {
return modelPool[parameters.id];
}
modelPool[parameters.id] = this;
this.id = parameters.id;
this.anotherModel= null;
// ...
}
}
const anotherModelPool = {};
class AnotherModel {
constructor(parameters = {}) {
if (anotherModelPool[parameters.id] instanceof AnotherModel) {
return anotherModelPool[parameters.id];
}
anotherModelPool[parameters.id] = this;
this.id = parameters.id;
this.models = [];
//...
}
}
或者作为类(不是实例)上的(不可枚举,不可写,不可配置)属性:
class Model {
constructor(parameters = {}) {
if (Model.pool[parameters.id] instanceof Model) {
return Model.pool[parameters.id];
}
Model.pool[parameters.id] = this;
this.id = parameters.id;
this.anotherModel= null;
//...
}
}
Object.defineProperty(Model, 'pool', {
value: {}
});
class AnotherModel {
constructor(parameters = {}) {
if (AnotherModel.pool[parameters.id] instanceof AnotherModel) {
return AnotherModel.pool[parameters.id];
}
AnotherModel.pool[parameters.id]
this.id = parameters.id;
this.models = [];
//...
}
}
Object.defineProperty(AnotherModel, 'pool', {
value: {}
});
由@Vardius添加,还可以创建一个伪抽象类(因为JS没有抽象类),可以从中扩展。使用new.target.name
,可以创建抽象类池中的命名空间:
class Entity {
constructor(parameters = {}) {
if (Entity.pool[this.constructor.name] && Entity.pool[this.constructor.name][parameters.id] instanceof Entity) {
return Entity.pool[new.target.name][parameters.id];
}
Entity.pool[new.target.name][parameters.id] = this;
}
}
Object.defineProperty(Entity, 'pool', {value: {} });