2009-12-28 18 views
8

मेरे पास Cat नामक एक टेबल है, और Cat नामक एक PHP वर्ग है। अब मैं CatDataMapper कक्षा बनाना चाहता हूं, ताकि Cat extends CatDataMapperडेटा मैपर आमतौर पर कैसा दिखता है?

मैं चाहता हूं कि डेटा मैपर क्लास ORM करने के लिए मूल कार्यक्षमता प्रदान करे, और बिल्ली बनाने, संपादित करने और हटाने के लिए।

उस उद्देश्य के लिए, शायद कोई भी जो इस पैटर्न को बहुत अच्छी तरह जानता है, मुझे कुछ सहायक सलाह दे सकता है? मुझे लगता है कि यह कुछ कार्यों जैसे अद्यतन(), हटाएं(), सेव() को प्रदान करने के लिए थोड़ा सा आसान होगा।

मुझे एहसास है कि डेटा मैपर में यह समस्या है: सबसे पहले आप बिल्ली का उदाहरण बनाते हैं, फिर नाम, फरकॉलर, आंखों के रंग, purrSound, meowSound, attendants, आदि जैसे सभी चर शुरू करें .. और सबकुछ स्थापित होने के बाद, आप Save() फ़ंक्शन को कॉल करें जिसे CatDataMapper से विरासत में मिला है। यह आसान था;) लेकिन अब, असली समस्या: आप बिल्लियों के लिए डेटाबेस से पूछताछ करते हैं और बिल्लियों के डेटा के साथ एक सादा उबाऊ परिणाम सेट वापस प्राप्त करते हैं।

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

एर ... ठीक है, यह प्रश्न वास्तव में छोटा रखने के लिए: यहां अच्छा अभ्यास क्या है?

उत्तर

12

DataMapper in PoEA

डाटा मैपर से सॉफ्टवेयर की एक परत है कि अलग करती है में स्मृति डेटाबेस से वस्तुओं है।इसकी ज़िम्मेदारी दो के बीच डेटा स्थानांतरित करने और प्रत्येक अन्य से अलग करने के लिए भी है। डेटा मैपर के साथ ऑब्जेक्ट्स को यह जानने की आवश्यकता नहीं है कि डेटाबेस मौजूद है; उन्हें कोई SQL इंटरफ़ेस कोड की आवश्यकता नहीं है, और निश्चित रूप से डेटाबेस स्कीमा का कोई ज्ञान नहीं है। ( डेटाबेस स्कीमा हमेशा ऑब्जेक्ट्स का उपयोग करने वाली वस्तुओं से अनजान है।) चूंकि यह मैपर (473) का रूप है, डेटा मैपर डोमेन परत से भी अज्ञात है।

इस प्रकार, बिल्ली को CatDataMapper का विस्तार नहीं करना चाहिए क्योंकि इससे संबंध बन जाएगा और बिल्ली को दृढ़ता परत से बांध देगा। यदि आप अपनी बिल्लियों से इस तरह से दृढ़ता से निपटने में सक्षम होना चाहते हैं, तो ActiveRecord या अन्य डेटा स्रोत वास्तुकला पैटर्न देखें।

डोमेन मॉडल का उपयोग करते समय आप आमतौर पर डेटामैपर का उपयोग करते हैं। एक साधारण डेटामैपर एक फ़ील्ड-टू-फील्ड आधार पर समकक्ष इन-मेमोरी क्लास में डेटाबेस तालिका को मैप करेगा। हालांकि, जब डेटामैपर की आवश्यकता उत्पन्न होती है, तो आमतौर पर आपके पास ऐसे सरल संबंध नहीं होंगे। टेबल्स आपकी ऑब्जेक्ट्स को 1: 1 मैप नहीं करेगा। इसके बजाय कई टेबल एक ऑब्जेक्ट एग्रीगेट और वाइसवर्सा में बना सकते हैं। नतीजतन, लागू करना सीआरयूडी विधियों, आसानी से काफी चुनौती बन सकता है।

इसके अलावा, यह अधिक जटिल पैटर्न (पीओईए में 15 पृष्ठों को शामिल करता है) में से एक है, जो अक्सर Repository pattern के साथ संयोजन में उपयोग किया जाता है। इसी तरह के प्रश्नों के लिए इस पृष्ठ के दाहिने तरफ संबंधित प्रश्न कॉलम देखें।

एक ही बिल्ली को संपादित करने वाले एकाधिक उपयोगकर्ताओं के बारे में आपके प्रश्न के लिए, यह Concurrency नामक एक आम समस्या है। इसका एक समाधान locking the row होगा, जबकि कोई इसे संपादित करेगा। लेकिन सबकुछ की तरह, यह lead to other issues कर सकता है।

+0

मेरे पास डेटा मैपर बनाम टेबल डेटा गेटवे (टीडीजी) के बारे में एक प्रश्न है। टीडीजी पैटर्न टेबल एक टेबल के साथ 1: 1 मानचित्र करता है, लेकिन अक्सर कुछ टीडीजी कक्षा विधियों में, हमें अन्य टेबल के साथ मुख्य तालिका में शामिल होने की आवश्यकता होती है (अतिरिक्त जानकारी चुनने के लिए कुछ पैरेंट टेबल के साथ जुड़ने के लिए)। क्या ऐसी चीज टेबल डेटा गेटवे पैटर्न का उल्लंघन करती है? आईएमएचओ जैसे ही आप टीडीजी कक्षा विधियों में एसक्यूएल स्टेटमेंट्स में अन्य डीबी टेबल (यहां तक ​​कि जुड़ते हैं) जोड़ते हैं, या अपने मॉडल (डोमेन मॉडल या टेबल डेटा) कक्षाओं को दो में विभाजित करते हैं - कक्षा डेटा मैपर क्लास बन जाती है। आईएमएचओ डाटा मैपर आपके टीडीजी कक्षाओं का एक सामान्य विकास है। – Centurion

+0

इसके अलावा, यदि आपका कार्यान्वित डेटा स्रोत वर्ग विभिन्न स्रोतों (डीबी या कुछ webservice) से कनेक्ट करने में सक्षम है तो IMHO आपने डेटा मैपर क्लास लागू किया है। – Centurion

+0

फाउलर पीओईएए में बताता है कि एक टीडीजी में कई तालिकाओं/विचारों तक पहुंचने के लिए कोड हो सकता है, इसलिए मुझे लगता है कि आप इसमें भी शामिल हो सकते हैं। लेकिन निश्चित रूप से इसका मतलब है कि लौटाए गए परिणाम तालिकाओं में 1: 1 से मेल नहीं खाते हैं और आपको सामान्य अपडेट के अलावा उन पंक्तियों के लिए विशेष अपडेट और सम्मिलित प्रश्नों की आवश्यकता होगी। मैं देख सकता हूं कि यह आपको कैसे निष्कर्ष निकालता है कि यह डेटा मैपर जैसा दिखता है लेकिन डेटा मैपर का उद्देश्य वास्तव में उससे कहीं अधिक जटिल है। यह सिर्फ जॉइन => डेटामैपर नहीं है। Http://css.dzone.com/books/practical-php-patterns/practical-php-patterns-data – Gordon

0

उत्तर कम रखें: आपके पास बिल्ली का एक उदाहरण है। (शायद यह CatDbMapper, या Cat3rdpartycatstoreMapper फैली) आप फोन:

$cats = $cat_model->getBlueEyedCats(); 
//then you get an array of Cat objects, in the $cats array 

तुम क्या प्रयोग करते हैं पता नहीं है, तो आप बेहतर समझ के लिए कुछ php ढांचे पर एक नज़र हो सकता है।

+0

मुझे लगता है कि आपने ActiveRecord का वर्णन किया है, डेटामैपर नहीं। –

2

आप ORM के Doctrine या Propel, बुनियादी सिद्धांत एक स्थिर वर्ग कि डेटाबेस से वास्तविक डेटा मिलेगा, (उदाहरण के लिए प्रोपेल CatPeer बनाना होगा) बनाने के लिए है, की तरह है और परिणाम सहकर्मी वर्ग के द्वारा प्राप्त पर भरोसा करते हैं फिर बिल्ली वस्तुओं में "हाइड्रेटेड" होगा।

हाइड्रेशन प्रक्रिया एक "सादा उबाऊ" MySQL परिणाम को गेटर्स और सेटर्स वाले अच्छे ऑब्जेक्ट्स में परिवर्तित करने की प्रक्रिया है।

तो एक पुनर्प्राप्ति के लिए आप CatPeer::doSelect() जैसे कुछ उपयोग करेंगे। फिर एक नई वस्तु के लिए आपको सबसे पहले यह दृष्टांत चाहते हैं (या निकालते हैं और डीबी से उदाहरण): $cat = new Cat();

प्रविष्टि कर के रूप में सरल होगा: $cat->save(); यह एक डालने के बराबर होगी (या अद्यतन करता है, तो ऑब्जेक्ट पहले से ही डीबी में मौजूद है ... ओआरएम को पता होना चाहिए कि, प्राथमिक कुंजी की मौजूदगी या अनुपस्थिति का उपयोग करके नई और मौजूदा वस्तुओं के बीच अंतर कैसे करें)।

1

पीडीओ में कुछ ओआरएम क्षमता बिल्ली उदाहरण बनाते हैं। आइए कहें कि मैं का उपयोग करता हूं, या यह भी कहता है कि मेरे पास mapDataset() फ़ंक्शन है जो सहयोगी सरणी लेता है। हालांकि, जैसे ही मुझे डेटा सेट से मेरा बिल्ली ऑब्जेक्ट मिला, I में अनावश्यक डेटा है। इसी समय, बीस उपयोगकर्ताओं डेटाबेस से ही बिल्ली डेटा लेने और संपादित बिल्ली वस्तु है, यानी बिल्ली का नाम बदलने, और बचाने() यह कर सकता है, जबकि अभी भी किसी अन्य उपयोगकर्ता एक और furColor स्थापना के बारे में बातें। जब वे सभी संपादन सहेजते हैं, तो सब कुछ गड़बड़ हो जाता है।

आदेश आम तौर पर डेटा के राज्य का ट्रैक रखने के लिए और IdentityMap और/या एक UnitOfWork में मैप किया संस्थाओं ... और अनुरोध चक्र अल संचालन के अंत पर सभी तेह विभिन्न कार्यों का रखें ट्रैक इस्तेमाल किया जाएगा तब किया जाएगा।

2

PHP मैपर लागू करना PHP < 5.3 में बहुत कठिन है, क्योंकि आप संरक्षित/निजी फ़ील्ड को पढ़/लिख नहीं सकते हैं।आप जब लोड हो रहा है और वस्तुओं की बचत में कुछ विकल्प हैं:

  1. वस्तु serializing की तरह, वैकल्पिक हल के कुछ प्रकार का उपयोग करें, संशोधित करने से यह स्ट्रिंग प्रतिनिधित्व है, और unserialize
  2. साथ इसे वापस लाने के सभी क्षेत्रों सार्वजनिक
  3. बनाओ
  4. पहली विधि एक नई रिलीज के साथ तोड़ने की संभावना है, और बहुत कच्चे हैक उन्हें

से प्रत्येक के लिए निजी/संरक्षित उन्हें रखें, और mutators/accessors लिखते हैं, एक दूसरे के एक (बहुत) माना जाता है बुरा अभ्यास

तीसरा विकल्प भी बुरा अभ्यास माना जाता है, क्योंकि आपको अपने सभी क्षेत्रों के लिए गेटर्स/सेटर्स नहीं प्रदान करना चाहिए, केवल उन्हीं को ही इसकी आवश्यकता है। आपका मॉडल शुद्ध डीडीडी (डोमेन संचालित डिज़ाइन) परिप्रेक्ष्य से "क्षतिग्रस्त" हो जाता है, क्योंकि इसमें विधियों की आवश्यकता होती है जो दृढ़ता तंत्र की वजह से आवश्यक होती हैं। इसका यह भी अर्थ है कि अब आपको खेतों के लिए एक और मैपिंग का वर्णन करना होगा -> फ़ील्ड के बगल में सेटटर विधियां -> तालिका कॉलम।

पीएचपी 5.3 उपयोग करने के लिए/प्रतिबिंब का उपयोग करके, खेतों के सभी प्रकार को बदलने की क्षमता का परिचय: इस के साथ

http://hu2.php.net/manual/en/reflectionproperty.setaccessible.php

, आप एक सच्चे डेटा नक्शाकार प्राप्त कर सकते हैं, क्योंकि सभी के लिए mutators प्रदान करने की आवश्यकता खेतों में से बंद कर दिया गया है।

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