2010-09-06 5 views
17

जैसा कि मैं अधिक से अधिक Grails का उपयोग कर रहा हूं, मैं खुद को कई नियंत्रकों में कोड लिख रहा हूं जो वास्तव में ऐसा लगता है कि यह एक डोमेन वर्ग का हिस्सा होना चाहिए। कभी-कभी, इस डोमेन कोड में सेवा कक्षा में कॉल होता है। उदाहरण के लिए, मैं हाल ही में एक डोमेन विधि है कि कुछ इस तरह देखा लिखा है:क्या डोमेन ऑब्जेक्ट्स से Grails सेवाओं को कॉल करने के लिए यह खराब डिज़ाइन है?

class Purchase { 

    // Injected 
    def paymentService 

    String captureTransactionId 
    Boolean captured 

    // ... 

    def capture() { 
     captureTransactionId = paymentService.capturePurchase(this) 
     captured = captureTransactionId != null 
    } 

मैं एकमुश्त गंदा लेखन इस कोड को नहीं लग रहा है, लेकिन मैं Grails में सबसे अच्छा डिजाइन प्रथाओं का एक अध्ययन नहीं किया है, इसलिए मैं कुछ राय प्राप्त करना चाहता था।

+0

देर से टिप्पणी: सेवाओं को इंजेक्शन कब दिया जाता है? उदाहरण के लिए, यदि आप किसी डेटाबेस से 10,000 खरीद लोड करते हैं, तो क्या भुगतान सेवा उन्हें इंजेक्शन दी जाएगी? प्रदर्शन में काफी नुकसान होगा। – wishihadabettername

+0

@ उपयोगकर्ता 277434 - हाइबरनेट वास्तव में इस प्रकार के बैच लोडिंग के लिए नहीं है। अगर मेरे पास कई बार लोड होने के लिए रिकॉर्ड थे, तो मैं हाइबरनेट का उपयोग करके छोड़ सकता हूं, या ऑब्जेक्ट सृजन से बचने के लिए प्रक्षेपण के साथ एक क्वेरी का उपयोग कर सकता हूं। –

उत्तर

15

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

लेकिन Grails डोमेन कक्षाओं में GORM विधियों में तारों द्वारा डीएओ की आवश्यकता को प्रतिस्थापित करता है, और डोमेन कक्षाओं में सत्यापन डालकर वैधकर्ताओं की आवश्यकता को भी प्रतिस्थापित करता है। इसलिए यह तय करते समय समस्याएं उत्पन्न होती हैं कि डोमेन क्लास में किस व्यवसाय तर्क को जाना चाहिए और किसी सेवा या अन्य सहायक सेवाओं में क्या होना चाहिए - सेवाओं को व्यावसायिक तर्क डालने के लिए एक उत्कृष्ट जगह बनाती है जिसे डोमेन क्लास विधि या सत्यापनकर्ता में आवश्यक हो सकता है।

हां यह ओओ-शुद्ध नहीं है, हाँ आप एक चक्र बनाते हैं (सेवा डोमेन क्लास और डोमेन क्लास सेवा को कॉल करती है), नहीं, यह "वसंत रास्ता" नहीं है लेकिन बहुत सारे Grails "वसंत नहीं है मार्ग"।

इस तरह के युग्मन से ऐप को घटकों के लिए घटकों या प्लगइन में अलग करना मुश्किल हो जाता है, लेकिन 'def भुगतान सेवा' के साथ सेवाओं की घोषणा करना बहुत मदद करता है क्योंकि आप पैकेज नाम या कार्यान्वयन के साथ नहीं हैं।

+0

हां, मैं ज्यादातर छोटे और केंद्रित घटकों के रूप में सेवाओं का उपयोग कर रहा हूं जो बाह्य प्रणालियों से बात करते हैं और फिर उन्हें कहीं भी समझते हैं। मुझे लगता है कि आपके द्वारा वर्णित इंजेक्शन मॉडल की वजह से वे पर्याप्त रूप से decoupled हैं। मुझे लेनदेन स्क्रिप्ट प्रकार के मॉडल से यह बहुत बेहतर लगता है कि @ डफिमो और @ammoQ सुझाव दे रहे हैं। –

+0

आप कहते हैं कि यह "वसंत रास्ता" नहीं है, लेकिन यहां वसंत के संस्थापक से एक प्रस्तुति है जिसमें वह वही करने की वकालत करता है: http://www.infoq.com/presentations/rod-johnson-are-we-here- अभी तक –

+0

मैं इसे करने का समर्थन करता हूं जो भी तरीका प्रभावी और कार्यान्वित करने के लिए आसान है, जो इस मामले में डोमेन क्लास के अंदर सेवा का उपयोग करना है। इसे सही करना एक किताब पर अच्छा लग रहा है, लेकिन ईमानदारी से, आप एक ही डेटाबेस का उपयोग कर एक अलग एप्लिकेशन के लिए कितनी बार अपने डोमेन कक्षाओं का उपयोग करने जा रहे हैं? भले ही यह बाद में आवश्यकता हो, फिर भी समस्या को हल करें, अभी नहीं। –

3

मुझे नहीं लगता कि डोमेन/मॉडल कक्षाओं को कॉलिंग सेवाएं होनी चाहिए। यह दूसरा रास्ता 'दौर होना चाहिए।

एक सेवा उपयोग के मामले को पूरा करने के लिए अन्य सेवाओं को व्यवस्थित कर सकती है। मुझे लगता है कि जाने का सही तरीका है।

+1

क्या आप अपनी राय के पीछे तर्क को समझा सकते हैं? यह दूसरे पर एक तरह से करने के लिए बेहतर या बदतर बनाता है? –

+0

मैं duffymo से सहमत हूं; कारण कम से कम आश्चर्य का सिद्धांत है। सेवा वर्ग को कॉल करने वाला एक डोमेन क्लास आश्चर्यजनक और एक मजबूत संकेत है कि जिम्मेदारियों को कक्षाओं को उचित रूप से असाइन नहीं किया गया है। –

+0

वह वसंत तरीका है, और वसंत Grails के लिए आधार है। – duffymo

3

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

इसके अलावा यह "someService.someUsefulMethod (myDomainInstance)" से कुछ "myDomainInstance.someUsefulMethod()" के साथ कोड को और अधिक पठनीय बनाता है (उम्मीद है कि आप जानते हैं कि मेरा क्या मतलब है)।

+0

हां, मुझे पता है कि आपका क्या मतलब है, और मैं वही महसूस करता हूं। मुझे जावा में एक पृथक इंटरफ़ेस का उपयोग करने और आपके डोमेन कोड को डीएओ कक्षाओं के कॉल करने के समान लगता है। ऐसा लगता है कि उस पैटर्न में गोरम जैसी प्रेरित चीजें हैं जहां आप डोमेन वर्ग को स्वयं को बचाने के लिए बताते हैं। मैं इसे एक ही चीज़ के रूप में देखता हूं। मैं भुगतान वर्ग को खुद को पकड़ने के लिए कहता हूं और यह देखभाल करने के लिए बाहरी प्रणाली से बात करता है। इस तरह, कम युग्मन है और मैंने एक बहुत ही प्रक्रियात्मक लग रही * लेनदेन-स्क्रिप्ट शैली * सेवा वर्ग लिखने से बचा है। –

0

मुझे यकीन नहीं है कि यह सही है या गलत है।

उदाहरण जैसे मामलों में, एक तरफ या दूसरे के बारे में क्या: या तो खरीद वर्ग के अंदर भुगतान सेवा.capturePurchase() कोड डालना, या आप सेवा में सभी तर्क डाल सकते हैं?

+0

क्योंकि मैं चिंताओं को अलग करना चाहता हूं और अपने घटकों के लिए एक जिम्मेदारी बनाए रखना चाहता हूं। मैं डोमेन कोड डोमेन तर्क को अद्यतन करना चाहता हूं, और मैं सेवा कोड बाहरी भुगतान प्रणाली के साथ बातचीत करना चाहता हूं। –

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

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