2016-04-28 14 views
8

मैं साधारण समस्या के बारे में सोच रहा हूं। मैं उदाहरण के लिए एक वर्ग दे दिया है 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)); 
      } 
     } 
    } 
} 

तो AnotherModelModel रों का संग्रह होता और Model वस्तु AnotherModel लिए संदर्भ है।

इस समस्या को हल करने के लिए अच्छा तरीका क्या है? हम जो हासिल करना चाहते हैं वह एक ही आईडी के साथ केवल एक वस्तु है।

जो मैं सोच रहा था वह किसी प्रकार का ऑब्जेक्टपूल करना है जहां मैं दिए गए वर्ग या कक्षाओं के लिए सभी ऑब्जेक्ट्स स्टोर करूंगा और जब नई ऑब्जेक्ट को तुरंत चालू किया जाएगा तो हमारा पूल एक नया बना देगा यदि यह अस्तित्व में नहीं है या मौजूदा को वापस कर रहा है?

लेकिन यहां थोड़ी सी हानि है, उदाहरण के लिए हमने पहले से ही कुछ कोड लिखा है, हमें new Model() से ObjectPool.get(Model, parameters) से उन्हें पुन: सक्रिय करने और बदलने के तरीके को बदलना होगा?

आपके विचार क्या हैं?

+0

ऊपर अपने परिदृश्य में, की 'AnotherModel' पहले बनाई गई एक उदाहरण है?या 'मॉडल' और 'अन्य मॉडेल' दोनों के उदाहरण व्यक्तिगत रूप से बनाए जा सकते हैं? मुझे यकीन नहीं है कि क्या मैं समझता हूं कि आपके कोड को किस तरह से काम करना चाहिए। – nils

+0

व्यक्तिगत रूप से, इससे कोई फर्क नहीं पड़ता कि हम पहले 'अन्य मॉडेल' या 'मॉडल' – Vardius

+0

बनाते हैं, मुझे खेद है कि यह एक बेवकूफ सवाल है, लेकिन क्या दोनों घटकों के लिए एक दूसरे के संदर्भ में रखना आवश्यक है? विशेष रूप से यह लाइन मुझे थोड़ा समझ में नहीं आती है: ': नया एल्डमोडेल (पैरामीटर.नॉदरमोडेल); '(' मॉडल 'में गुजरने के बिना मॉडल से' अन्य मॉडेल 'बनाना) – nils

उत्तर

3

आप अपने उदाहरणों का ट्रैक रखने के लिए किसी ऑब्जेक्ट पूल (या तो कक्षा या उसके बाहर) का उपयोग कर सकते हैं। id पहले से ही पूल में मौजूद है

new Model(); 
new AnotherModel(); 

हैं, तो आप सिर्फ मौजूदा उदाहरण लौट सकते हैं: निर्माता में यह परिभाषित करके, आप अभी भी साथ मॉडल का दृष्टांत कर सकते हैं। वर्ग के

बाहर:

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: {} 
}); 

के रूप में @ वर्डियस द्वारा जोड़ा गया, कोई भी छद्म-अमूर्त वर्ग भी बना सकता है (क्योंकि जेएस में अमूर्त कक्षाएं नहीं हैं) जिन्हें से बढ़ाया जा सकता है। 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: {} }); 
+0

पूल का उपयोग करने के लिए भी प्रयास करते हैं, यदि मैं एक सार वर्ग' सार मॉडोडेल 'बनाता हूं और इस वर्ग के लिए केवल संपत्ति' पूल 'को परिभाषित करता हूं और फिर अन्य सभी मॉडल इसका विस्तार करेंगे। क्या ये काम करेगा ? – Vardius

+0

मुझे मैट्रिक्स को परिभाषित करना होगा, फिर भी कई वर्गों के लिए 'constructor.name' को स्टोर करने के लिए – Vardius

+0

शायद नहीं, क्योंकि' पूल' एक उदाहरण नहीं होना चाहिए ('this.pool') या प्रोटोटाइप (' सार मॉडोड.प्रोटोटाइप.pool') संपत्ति। यदि यह एक उदाहरण संपत्ति थी, तो यह काम नहीं करेगा क्योंकि यह हर उदाहरण के लिए बनाया जाएगा। जब तक आप 'सार मॉडोड' श्रेणी में 'सार मॉडोड' वर्ग पर किसी संपत्ति के रूप में पूल में लिख नहीं सकते हैं और सभी बाल-वर्गों के लिए नामस्थान नहीं रख सकते हैं। यहाँ – nils

संबंधित मुद्दे