रनटाइम पर कक्षा को फ़ील्ड जोड़ना - डिज़ाइन पैटर्न


15

अपने ग्राहक की कल्पना करें कि उनके CMS में उनके नाइयों में उत्पाद में नई संपत्ति (जैसे रंग) जोड़ने की संभावना है।

फ़ील्ड के रूप में गुण होने के बजाय:

class Car extends Product {
   protected String type;
   protected int seats;
}

आप शायद कुछ ऐसा करना चाहेंगे:

class Product {
   protected String productName;
   protected Map<String, Property> properties;
}

class Property {
   protected String name;
   protected String value;
}

यही है, मौजूदा एक के ऊपर खुद के प्रकार की प्रणाली बनाना। यह मेरे लिए ऐसा लगता है कि डोमेन विशिष्ट लैंग गेज बनाने के रूप में देखा जा सकता है, या नहीं?

क्या यह दृष्टिकोण एक ज्ञात डिजाइन पैटर्न है? क्या आप समस्या को अलग तरीके से हल करेंगे? मुझे पता है कि ऐसी भाषाएं हैं जहां मैं रनटाइम में एक फ़ील्ड जोड़ सकता हूं, लेकिन डेटाबेस के बारे में क्या? क्या आप इसके बजाय कॉलम जोड़ेंगे / बदलेंगे या ऊपर दिखाए अनुसार कुछ का उपयोग करेंगे?

अपना समय देने के लिए धन्यवाद :)।



निश्चित नहीं है कि आप किस भाषा का उपयोग कर रहे हैं, लेकिन अगर यह C # है तो आप एक डायनामिक प्रकार का उपयोग कर सकते हैं जो मूल रूप से एक केवीपी को शब्दकोश थोड़े में संग्रहीत करता है जैसे कि आप उत्पादों पर क्या कर रहे हैं और आपको सीधे उन्हें जोड़ने के लिए बिना गुणों के बस से निपटने की अनुमति देता है। संग्रह के रूप में संग्रह। हालांकि आपके पास मजबूत टाइपिंग नहीं होगी। मुझे पता है कि आपने एक डिज़ाइन पैटर्न के लिए कहा था, लेकिन मुझे नहीं लगता कि आपको उनका उपयोग करने के लिए कुछ भी जटिल की आवश्यकता होगी। msdn.microsoft.com/en-us/magazine/gg598922.aspx
टोनी

टोनी: मैं यहां जावा का उपयोग कर रहा हूं, लेकिन इसे छद्म कूप :) पर विचार करें। C # मुझे डेटाबेस में उस गतिशील वस्तु को बनाए रखने की अनुमति देगा? मुझे संदेह है, क्योंकि डेटाबसे को सामने वाले डेटा की संरचना को जानना होगा।
फिलीप

नहीं है राज्य Desing पैटर्न एक-la गिरोह के-चार है, जो एक वस्तु बना देता है दिखाई देते हैं अपने को बदलने के लिए प्रकार या वर्ग रन-टाइम में। अन्य विकल्प ऑब्जर्वर डिज़ाइन पैटर्न या एक प्रॉक्सी डिज़ाइन पैटर्न हैं
निकोस एम।

1
सिर्फ मानचित्र डेटाटाइप का उपयोग क्यों न करें? DB में इसे {id} + {id, key, value} के रूप में दर्शाया जा सकता है, यदि आप प्रदर्शन के लिए नहीं पूछ रहे हैं।
शैडो इन रेन

जवाबों:


4

बधाई हो! आपने अभी-अभी प्रोग्रामिंग लैंग्वेज / टाइप सिस्टम ग्लोब को सर्कुलेट किया है, जो आपने विदा ली दुनिया की दूसरी ओर पहुंची है। आप सिर्फ गतिशील भाषा / प्रोटोटाइप-आधारित वस्तु भूमि की सीमा पर आ गए हैं!

कई गतिशील भाषाएं (जैसे जावास्क्रिप्ट, पीएचपी, पायथन) किसी को रनटाइम पर ऑब्जेक्ट गुण का विस्तार करने या बदलने की अनुमति देती हैं।

इसका चरम रूप स्व या जावास्क्रिप्ट जैसी प्रोटोटाइप आधारित भाषा है । उनके पास कक्षाएं नहीं हैं, सख्ती से बोल रहा हूं। आप उन चीजों को कर सकते हैं जो वंशानुक्रम के साथ वर्ग-आधारित, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग जैसी दिखती हैं, लेकिन जावा और C # जैसी अधिक तेजी से परिभाषित, वर्ग-आधारित भाषाओं की तुलना में नियमों में बहुत ढील दी गई है।

PHP और Python जैसी लैंगगॉज बीच मैदान में रहती हैं। उनके पास नियमित, मुहावरेदार वर्ग-आधारित प्रणालियाँ हैं। लेकिन ऑब्जेक्ट विशेषताओं को रनटाइम पर जोड़ा, बदला या हटाया जा सकता है - कुछ प्रतिबंधों के साथ (जैसे "अंतर्निहित प्रकारों को छोड़कर") जो आपको जावास्क्रिप्ट में नहीं मिलते हैं।

इस गतिशीलता के लिए बड़ा व्यापार प्रदर्शन है। भूल जाएं कि भाषा कितनी दृढ़ता से या कमजोर रूप से टाइप की गई है, या इसे मशीन कोड में कितनी अच्छी तरह संकलित किया जा सकता है। सरल वस्तुओं के बजाय गतिशील वस्तुओं को लचीले नक्शे / शब्दकोशों के रूप में दर्शाया जाना चाहिए। यह प्रत्येक ऑब्जेक्ट एक्सेस के लिए ओवरहेड जोड़ता है। कुछ कार्यक्रम इस ओवरहेड को कम करने के लिए बहुत अधिक लंबाई तक जाते हैं (जैसे कि पायथन क्वरग असाइनमेंट और पायथन में स्लॉट-आधारित कक्षाएं), लेकिन अतिरिक्त ओवरहेड आमतौर पर पाठ्यक्रम और प्रवेश की कीमत के बराबर है।

अपने डिज़ाइन पर वापस आ रहे हैं, आप अपनी कक्षाओं के सबसेट पर गतिशील गुण रखने की क्षमता तैयार कर रहे हैं। A Productमें परिवर्तनशील गुण हो सकते हैं; मुमकिन है कि Invoiceकोई Orderऐसा कर सकता है या नहीं। यह एक बुरा तरीका नहीं है। यह आपको एक सख्त, अनुशासित भाषा और प्रकार प्रणाली में रहते हुए, जहाँ आपको इसकी आवश्यकता है, वहाँ भिन्नता प्रदान करने की सुविधा देता है। नीचे की तरफ, आप उन लचीले गुणों को प्रबंधित करने के लिए जिम्मेदार हैं, और आपको संभवतः ऐसा तंत्र के माध्यम से करना होगा जो अधिक देशी विशेषताओं से थोड़ा अलग दिखता है। p.prop('tensile_strength')इसके बजाय p.tensile_strength, उदाहरण के लिए, और p.set_prop('tensile_strength', 104.4)इसके बजायp.tensile_strength = 104.4। लेकिन मैंने पास्कल, एडा, सी, जावा और यहां तक ​​कि गतिशील भाषाओं में कई कार्यक्रमों के साथ काम किया है और गैर-मानक विशेषता प्रकारों के लिए बिल्कुल ऐसे गेट्टर-सेटर का उपयोग किया है; दृष्टिकोण स्पष्ट रूप से व्यावहारिक है।

वैसे, स्थैतिक प्रकारों और अत्यधिक विविध दुनिया के बीच यह तनाव बेहद सामान्य है। डेटाबेस स्कीमा को डिजाइन करते समय एक विशेष समस्या अक्सर देखी जाती है, खासकर रिलेशनल और प्री-रिलेशनल डेटा स्टोर के लिए। कभी-कभी यह "सुपर-पंक्तियों" को बनाकर निपटा दिया जाता है जिसमें सभी कल्पित विविधताओं के मिलन को परिभाषित करने या परिभाषित करने के लिए पर्याप्त लचीलापन होता है, फिर उन क्षेत्रों में आने वाले किसी भी डेटा को भरा जाता है। वर्डप्रेस wp_postsतालिका , उदाहरण के लिए, जैसे क्षेत्रों है comment_count, ping_status, post_parentऔर post_date_gmtहै कि केवल कुछ परिस्थितियों में दिलचस्प हैं, और व्यवहार में अक्सर खाली जाना है। एक और दृष्टिकोण एक बहुत ही अतिरिक्त, सामान्यीकृत तालिका है wp_options, जैसे बहुत कुछPropertyकक्षा। हालांकि इसके लिए अधिक स्पष्ट प्रबंधन की आवश्यकता होती है, लेकिन इसमें आइटम शायद ही कभी खाली होते हैं। ऑब्जेक्ट-ओरिएंटेड और डॉक्यूमेंट डेटाबेस (जैसे MongoDB) में अक्सर बदलते विकल्पों के साथ काम करने का एक आसान समय होता है, क्योंकि वे अपनी इच्छानुसार विशेषताओं को बना और सेट कर सकते हैं।


0

मुझे सवाल पसंद है, मेरे दो सेंट:

आपके दो दृष्टिकोण मौलिक रूप से भिन्न हैं:

  • पहला OO ans दृढ़ता से टाइप किया गया है - लेकिन एक्सटेंसिबल नहीं है
  • दूसरा कमजोर रूप से टाइप किया गया है (स्ट्रिंग कुछ भी एनकैप्सुलेट करता है)

C ++ में, कई लोग एक std :: बढ़ावा देने के नक्शे का उपयोग करेंगे :: दोनों के मिश्रण को प्राप्त करने के लिए संस्करण

व्यवधान: ध्यान दें कि कुछ भाषाएँ, जैसे कि C #, प्रकारों के गतिशील निर्माण की अनुमति देती हैं। जो गतिशील रूप से सदस्यों को जोड़ने के सामान्य मुद्दे का एक अच्छा समाधान हो सकता है। हालांकि, संकलन के बाद "संशोधित / जोड़ना" प्रकार स्वयं सिस्टम को भ्रष्ट करता है, और आपके "संशोधित" प्रकारों को लगभग बेकार कर देता है (जैसे, आप इस तरह के अतिरिक्त गुणों तक कैसे पहुंच सकते हैं, क्योंकि आप नहीं जानते कि वे भी मौजूद हैं? केवल उचित तरीका होगा? प्रत्येक वस्तु पर एक व्यवस्थित प्रतिबिंब हो ... एक शुद्ध गतिशील भाषा के साथ समाप्त होना _ आप 'गतिशील' .NET कीवर्ड का उल्लेख कर सकते हैं)


रनटाइम सीम पर प्रकार बनाना दिलचस्प है, लेकिन मेरे लिए बहुत अधिक आकर्षक है (मैं जावा में प्रोग्रामिंग कर रहा हूं)। इस तरह का समाधान काम नहीं करेगा, अगर मैं डेटाबसे में ऑब्जेक्ट को स्टोर करना चाहूंगा, जो हमेशा दृढ़ता से टाइप किया जाता है I belive। मेरे द्वारा प्रस्तावित कमजोर टाइप समाधान को आसानी से डेटाबेस में संग्रहीत किया जा सकता है।
फिलिप

0

रनटाइम में एक प्रकार का निर्माण करना बहुत अधिक जटिल लगता है और फिर एक अमूर्त परत का निर्माण होता है। डिकूप्ल सिस्टम के लिए एक अमूर्त बनाना बहुत आम है।

मुझे अपने अभ्यास से एक उदाहरण दिखाते हैं। मॉस्को एक्सचेंज में व्यापारी के एपीआई के साथ प्लाजा 2 नामक ट्रेडिंग कोर है। व्यापारी वित्तीय डेटा के साथ काम करने के लिए अपने कार्यक्रम लिखते हैं। समस्या यह है कि यह डेटा बहुत विशाल, जटिल है, और परिवर्तनों के लिए अत्यधिक उजागर है। किसी नए वित्तीय उत्पाद के आने के बाद यह बदल सकता है या समाशोधन की रॉल बदल सकता है। भविष्य के परिवर्तनों की प्रकृति की भविष्यवाणी नहीं की जा सकती है। सचमुच, यह हर दिन बदल सकता है और गरीब प्रोग्रामर को कोड को संपादित करना चाहिए और एक नया संस्करण जारी करना चाहिए, और नाराज व्यापारियों को अपने सिस्टम को संशोधित करना चाहिए।

स्पष्ट निर्णय एक अमूर्तता के पीछे सभी वित्तीय नरक को छिपाना है। उन्होंने अच्छी तरह से ज्ञात एसक्यूएल तालिकाओं का उपयोग किया है। उनके कोर का सबसे बड़ा हिस्सा किसी भी मान्य स्कीमा के साथ काम कर सकता है, व्यापारी के सॉफ्टवेयर को स्कीमा को पार्स कर सकते हैं और पता लगा सकते हैं कि यह उनके सिस्टम के अनुकूल है या नहीं।

अपने उदाहरण पर वापस लौटते हुए, कुछ तर्क के सामने एक अमूर्त भाषा बनाना सामान्य है। यह "संपत्ति", "तालिका", "संदेश", या यहां तक ​​कि मानव भाषा भी हो सकती है, लेकिन इस दृष्टिकोण की कमियों पर ध्यान दें:

  • पार्सिंग और सत्यापन के लिए अधिक कोड (और पाठ्यक्रम से अधिक समय)। स्टैटिक टाइपिंग के साथ आपके लिए जो कुछ भी कंपाइलर ने किया वह आपको रन-टाइम में करना होगा।
  • संदेशों, तालिकाओं या अन्य प्राइमेटिक्स के अधिक प्रलेखन। सभी जटिलता कोड से किसी प्रकार के स्कीमा या standart में जाती है। यहाँ उपर्युक्त वित्तीय नरक स्कीमा का एक उदाहरण दिया गया है: http://ftp.moex.com/pub/FORTS/Plaza2/p2gate_en.pdf (तालिकाओं के दर्जनों पृष्ठ)

0

क्या यह दृष्टिकोण एक ज्ञात डिजाइन पैटर्न है?

XML और HTML में, ये एक नोड / तत्व के गुण होंगे। मैंने उन्हें विस्तारित गुण, नाम / मूल्य जोड़े, और मापदंडों को भी सुना है।

क्या आप समस्या को अलग तरीके से हल करेंगे?

इस तरह मैं समस्या का समाधान करूँगा, हाँ।

मुझे पता है कि ऐसी भाषाएं हैं जहां मैं रनटाइम में एक फ़ील्ड जोड़ सकता हूं, लेकिन डेटाबेस के बारे में क्या?

एक डेटाबेस कुछ इंद्रियों में जावा की तरह होगा। छद्म वर्ग में:

TABLE products
(
    product_name VARCHAR(50),
    product_id INTEGER AUTOINCREMENT
)

TABLE attributes
(
    product_id INTEGER,
    name VARCHAR(50),
    value VARCHAR(2000)
)

यह जावा के अनुरूप होगा

class Product {
   protected String productName;
   protected Map<String, String> properties;
}

ध्यान दें कि प्रॉपर्टी क्लास की कोई आवश्यकता नहीं है, क्योंकि मैप नाम को कुंजी के रूप में संग्रहीत करता है।

क्या आप इसके बजाय कॉलम जोड़ेंगे / बदलेंगे या ऊपर दिखाए अनुसार कुछ का उपयोग करेंगे?

मैंने कॉलम चीज़ जोड़ने / बदलने की कोशिश की है, और यह एक बुरा सपना था। यह किया जा सकता है, लेकिन चीजें सिंक से बाहर हो रही हैं और मुझे इसे अच्छी तरह से काम करने के लिए कभी नहीं मिला। तालिका संरचना जो मैंने ऊपर उल्लिखित की है, वह अधिक सफल रही है। आप के द्वारा खोज करता है और आदेश क्या करने की जरूरत है, तो एक प्रत्येक डेटा प्रकार (के लिए तालिका गुण उपयोग करने पर विचार date_attributes, currency_attributes, आदि) या उत्पादों तालिका में अच्छे पुराने डेटाबेस स्तंभों के रूप में गुण के कुछ जोड़ने। रिपोर्ट्स अक्सर डेटाबेस कॉलम पर उप तालिकाओं पर लिखना बहुत आसान होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.