2017-11-08 5 views
2

GoogleとStackOverflowでインスタンスのキャッシュとシングルトンを検索しようとしましたが、これに答える投稿を知っていれば、module.exportsに関する投稿のみが表示されます質問、それを参照して自由に感じる。ありがとうございました!ノード+ ES6クラス:キャッシュされたオブジェクトのセットを設定する

私はほとんど変更されないオブジェクトのセットを処理する必要があるため、パフォーマンスの最適化のためにキャッシュする必要があるアプリケーションがあります。

おもちゃの例ここでは単一のプロパティが直接設定されています。

私はアプリケーションを呼び出すと、私はassets_cached.jsにキャッシュされたオブジェクトのセットが含まれますオブジェクトをエクスポートします。私はES6クラスを持つアプリケーションの別のモジュールで

const Assets = {}; 
module.exports.Assets = Assets; 

const _ = require('lodash') 
const { Assets } = require('./assets_cached') 

class Asset { 
    constructor(id, some_property) { 
     if (id in Assets) { 
      // Update instance data with cached properties 
      _.assign(this, Assets_cached[id]); 
     } else { 
      // If it's not cached, create a new object 
      this.id = id; 
      this.some_property = some_property; 
      // Cache this object 
      Assets_cached[id] = this; 
     } 
    } 

    getProperty() { 
     return this.some_property; 
    } 

    setProperty(value) { 
     this.some_property = value; 
     // Is there a way of avoiding having to do this double assignment? 
     Assets_cached[id].some_property = value; 
    } 
} 
module.exports = Asset; 

some_propertyを2回(現在のインスタンスとキャッシュで、他のインスタンスが並行して更新されていることを確認しながら)設定する必要はありませんか?

理想的には私のような何かをしたいと思います:コンストラクタの内部

if (id in Assets) { 
    this = Assets.cached[id] 
} 

を、これは不可能です。

この作品を作成する最もエレガントで正しい方法は何ですか?

+0

なぜ、同じアセットに対して複数の「Asset」インスタンスを持ちたいのですか? – Bergi

+1

コンストラクタ内のキャッシングを処理したくない。コンストラクタは、インスタンスを作成するために必要最小限のコード用の場所です。しかし、すべての追加ロジックを 'Assets.create'のようなファクトリ関数に移すことについて考えるかもしれません。これはBergiの最初の素早い解答とうまく連動します。 –

答えて

2

理想的には私はここに魔法のキーワードはreturnあるコンストラクタ

this = Assets.cached[id]ような何かをしたいと思います。ちょうどreturn an arbitrary object from the constructorであり、thisの代わりに使用されます。ここで

constructor(id, some_property) { 
    if (id in Assets) { 
     // use cached instance instead of creating a new one 
     return Assets_cached[id]; 
    } else { 
     this.id = id; 
     this.some_property = some_property; 
     // Cache this object 
     Assets_cached[id] = this; 
    } 
} 
+0

ありがとうBergi、それは非常に便利です、私はNodeとJSに比較的新しいですし、それほど簡単であるとは期待していませんでした。 – alexvicegrab

1

the comment that was made some half an hour agoへのアプローチです...

const { Assets_cached } = require('./assets_cached'); 
// const { AssetStore } = require('./assetstore'); 

class Asset { 
    constructor(id, some_property) { // clean/lean constructor. 
     this.id = id; 
     this.some_property = some_property; 
    } 
    getProperty() { 
     return this.some_property; 
    } 
    setProperty(value) { 
     this.some_property = value; 
    } 
} 

function isAsset(type) { 
    // poor man's approach ... change to something more feasible. 
    return (type instanceof Asset); 
} 

function createAsset(id, some_property) { // factory that also handles caching. 
    var 
     asset = Assets_cached[id]; 
    // asset = AssetStore.get(id); 

    if (!(asset && isAsset(asset))) { 

     asset = Assets_cached[id] = (new Asset(id, some_property)); 
    // AssetStore.put(id, (asset = new Asset(id, some_property))); 
    } 
    return asset; 
} 

module.exports = { 
    create : createAsset, 
    isAsset : isAsset 
}; 

1つはまたgetAssets_cachedput/setのようなものを最小限のAPIを提供することを検討すべきですAssets_cachedの代わりにdeleteが完全に露出している、pキー値ストアがありません。

+0

Peterに感謝します。私は最初は工場を使用していましたが、コードの一部は既に実稼働していますので、コンストラクタから既存のオブジェクトを返す必要があります。 – alexvicegrab

関連する問題