क्या आप आम तौर पर वस्तुओं या उनके सदस्य चर को कार्यों में भेजते हैं?


31

जो आम तौर पर इन दो मामलों के बीच अभ्यास स्वीकार किया जाता है:

function insertIntoDatabase(Account account, Otherthing thing) {
    database.insertMethod(account.getId(), thing.getId(), thing.getSomeValue());
}

या

function insertIntoDatabase(long accountId, long thingId, double someValue) {
    database.insertMethod(accountId, thingId, someValue);
}

दूसरे शब्दों में, यह आम तौर पर पूरे ऑब्जेक्ट्स को पास करने के लिए बेहतर है या सिर्फ उन क्षेत्रों में जिनकी आपको ज़रूरत है?


5
यह पूरी तरह से इस बात पर निर्भर करता है कि फ़ंक्शन क्या है और यह प्रश्न में ऑब्जेक्ट से कैसे संबंधित है (या संबंधित नहीं है)।
मेटाफ़ाइट

यही समस्या है। मैं नहीं बता सकता कि मैं एक या दूसरे का उपयोग कब करूंगा। मुझे लगता है कि मैं या तो दृष्टिकोण को समायोजित करने के लिए कोड को हमेशा बदल सकता हूं।
एजेजे

1
एपीआई के संदर्भ में (और कार्यान्वयन को बिल्कुल नहीं देख रहे हैं), पूर्व सार और डोमेन उन्मुख (जो अच्छा है), जबकि बाद वाला नहीं है (जो बुरा है)।
एरिक Eidt

1
पहला दृष्टिकोण 3-स्तरीय OO होगा। लेकिन विधि से शब्द डेटाबेस को समाप्त करके यह और भी अधिक होना चाहिए। यह "स्टोर" या "पर्सिस्ट" होना चाहिए और अकाउंट या थिंग (दोनों नहीं) होना चाहिए। इस परत के ग्राहक के रूप में आपको भंडारण माध्यम की जानकारी नहीं होनी चाहिए। खाता पुनर्प्राप्त करते समय आपको वांछित वस्तु की पहचान करने के लिए आईडी या संपत्ति मूल्यों (क्षेत्र मान नहीं) के संयोजन की आवश्यकता होगी। या / और एक गणना विधि जो सभी खातों को पारित करती है।
मार्टिन माट

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

जवाबों:


24

न तो आम तौर पर दूसरे की तुलना में बेहतर है। यह एक निर्णय कॉल है जिसे आपको केस-बाय-केस आधार पर करना है।

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

इस निर्णय को करने का सबसे आसान तरीका यह है कि वस्तु को बदलने पर क्या कोड होना चाहिए या नहीं बदलना चाहिए । आइए अपने उदाहरण का थोड़ा विस्तार करें:

function addWidgetButtonClicked(clickEvent) {
    // get form data
    // get user's account
    insertIntoDatabase(account, data);
}
function insertIntoDatabase(Account account, Otherthing data) {
    // open database connection
    // check data doesn't already exist
    database.insertMethod(account.getId(), data.getId(), data.getSomeValue());
}

बनाम

function addWidgetButtonClicked(clickEvent) {
    // get form data
    // get user's account
    insertIntoDatabase(account.getId(), data.getId(), data.getSomeValue());
}
function insertIntoDatabase(long accountId, long dataId, double someValue) {
    // open database connection
    // check data doesn't already exist
    database.insertMethod(accountId, dataId, someValue);
}

पहले संस्करण में, यूआई कोड dataऑब्जेक्ट को नेत्रहीन रूप से पास कर रहा है और इसमें से उपयोगी फ़ील्ड निकालने के लिए डेटाबेस कोड पर निर्भर है। दूसरे संस्करण में, यूआई कोड dataऑब्जेक्ट को उसके उपयोगी क्षेत्रों में तोड़ रहा है , और डेटाबेस कोड उन्हें सीधे यह जानने के बिना प्राप्त करता है कि वे कहां से आए थे। मुख्य निहितार्थ यह है कि, यदि dataऑब्जेक्ट की संरचना को किसी तरह से बदलना है, तो पहले संस्करण को केवल डेटाबेस कोड को बदलना होगा, जबकि दूसरे संस्करण को बदलने के लिए केवल यूआई कोड की आवश्यकता होगी । उन दोनों में से कौन सा सही है यह काफी हद तक इस बात पर निर्भर करता है कि dataऑब्जेक्ट में किस तरह का डेटा है , लेकिन यह आमतौर पर बहुत स्पष्ट है। उदाहरण के लिए, यदिdata"20/05/1999" जैसे एक उपयोगकर्ता द्वारा प्रदान किया गया स्ट्रिंग है, इसे Dateपास करने से पहले इसे उचित प्रकार में परिवर्तित करने के लिए UI कोड तक होना चाहिए ।


8

यह एक संपूर्ण सूची नहीं है, लेकिन एक तर्क के रूप में एक वस्तु को विधि में पारित किया जाना चाहिए या नहीं यह तय करते समय निम्नलिखित कारकों में से कुछ पर विचार करें:

क्या वस्तु अपरिवर्तनीय है? क्या कार्य 'शुद्ध' है?

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

अंगूठे के एक नियम के रूप में, यह सुनिश्चित करने का लक्ष्य रखें, जहां तक ​​संभव हो, यह सुनिश्चित करें कि किसी भी वस्तु को एक विधि से गुजरना स्पष्ट रूप से अपरिवर्तनीय है।

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

विधि के पास पहले से कितने तर्क हैं?

अत्यधिक लंबी तर्क सूचियों वाली विधियाँ (भले ही उनमें से अधिकांश तर्कों में 'डिफ़ॉल्ट' मान हों) एक कोड गंध की तरह दिखाई देने लगती हैं। हालांकि, कभी-कभी ऐसे कार्य आवश्यक होते हैं, और आप एक ऐसा वर्ग बनाने पर विचार कर सकते हैं, जिसका एकमात्र उद्देश्य एक पैरामीटर ऑब्जेक्ट की तरह कार्य करना है ।

इस दृष्टिकोण में आपके पैरामीटर ऑब्जेक्ट से आपके 'स्रोत' ऑब्जेक्ट से अतिरिक्त बॉयलरप्लेट कोड मैपिंग की एक छोटी राशि शामिल हो सकती है, लेकिन प्रदर्शन और जटिलता दोनों के मामले में यह काफी कम लागत है, और डिकॉउलिंग के संदर्भ में कई लाभ हैं। और ऑब्जेक्ट अपरिवर्तनीयता।

क्या उत्तीर्ण वस्तु विशेष रूप से आपके आवेदन के भीतर एक "परत" से संबंधित है (उदाहरण के लिए, एक ViewModel, या ORM इकाई?)

चिंता (SoC) के अलगाव के बारे में सोचें । कभी-कभी अपने आप से पूछें कि क्या वस्तु उसी परत या मॉड्यूल के लिए "संबंधित" है जिसमें आपकी विधि मौजूद है (उदाहरण के लिए एक हाथ से संचालित एपीआई रैपर लाइब्रेरी, या आपका कोर बिजनेस लॉजिक लेयर, आदि) सूचित कर सकता है कि क्या उस वस्तु को वास्तव में पास किया जाना चाहिए। तरीका।

SoC स्वच्छ, शिथिल-युग्मित, मॉड्यूलर कोड लिखने के लिए एक अच्छी नींव है। उदाहरण के लिए, एक ORM निकाय ऑब्जेक्ट (आपके कोड और आपके डेटाबेस स्कीमा के बीच मैपिंग) आदर्श रूप से आपकी व्यावसायिक परत में या आपकी प्रस्तुति / UI परत में खराब नहीं होना चाहिए।

'परतों' के बीच डेटा पास करने के मामले में, एक विधि में पारित सादे डेटा पैरामीटर आमतौर पर 'गलत' परत से एक वस्तु में गुजरने पर बेहतर होता है। हालाँकि यह एक अलग विचार है कि अलग मॉडल हैं जो 'सही' परत पर मौजूद हैं जो आप इसके बजाय मैप कर सकते हैं।

क्या कार्य ही बहुत बड़ा और / या जटिल है?

जब किसी फ़ंक्शन को बहुत अधिक डेटा आइटम की आवश्यकता होती है, तो यह विचार करने योग्य हो सकता है कि क्या यह फ़ंक्शन बहुत अधिक जिम्मेदारियों पर ले रहा है; छोटी वस्तुओं और छोटे, सरल कार्यों का उपयोग करके रिफ्लेक्टर के संभावित अवसरों की तलाश करें।

फ़ंक्शन एक कमांड / क्वेरी ऑब्जेक्ट होना चाहिए?

कुछ मामलों में डेटा और फ़ंक्शन के बीच संबंध निकट हो सकता है; उन मामलों में विचार करें कि क्या कमांड ऑब्जेक्ट या क्वेरी ऑब्जेक्ट उचित होगा।

क्या एक विधि के लिए एक वस्तु पैरामीटर जोड़ने से वर्ग को नई निर्भरताएं अपनाने के लिए मजबूर किया जाता है?

कभी-कभी "प्लेन पुराने डेटा" तर्कों के लिए सबसे मजबूत तर्क यह है कि प्राप्त करने वाला वर्ग पहले से ही बड़े करीने से आत्म-निहित है, और इसके तरीकों में से एक में ऑब्जेक्ट पैरामीटर को जोड़ने से कक्षा प्रदूषित हो जाएगी (या यदि कक्षा पहले से ही प्रदूषित है, तो यह होगा) मौजूदा एन्ट्रापी को और भी खराब बनायें)

क्या आपको वास्तव में एक पूर्ण वस्तु के आसपास से गुजरने की आवश्यकता है या क्या आपको केवल उस वस्तु के इंटरफेस के एक छोटे से हिस्से की आवश्यकता है?

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


5

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

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

सामान्य तौर पर , यदि यह अस्पष्ट है, तो कार्य करने के लिए आवश्यक सबसे छोटे डेटा का पक्ष लेते हैं। अक्सर इसका मतलब सिर्फ खेतों में गुजरना है, क्योंकि फ़ंक्शन को ऑब्जेक्ट में पाए जाने वाले अन्य सामान की आवश्यकता नहीं है। लेकिन कभी-कभी संपूर्ण वस्तु को लेना अधिक सही होता है क्योंकि इससे भविष्य में चीजें अनिवार्य रूप से बदल जाती हैं।


आप सम्मिलित करने के लिए विधि का नाम क्यों नहीं बदलते हैं। क्या आप किसी अन्य प्रकार को पारित करने जा रहे हैं? Obj का उपयोग करने के लिए निश्चित संख्या में तर्कों को कोड पढ़ने में आसानी होती है। आपके मामले में मैं यह सोचता हूं कि यदि विधि नाम स्पष्ट करता है कि मैं क्या करने जा रहा हूं तो इसके बजाय मैं इसे कैसे सम्मिलित करने जा रहा हूं।
Laiv

3

निर्भर करता है।

विस्तृत करने के लिए, आपके द्वारा स्वीकार किए जाने वाले मापदंडों को शब्दार्थ से मेल खाना चाहिए। एक EmailInviterऔर inviteविधि के इन तीन संभावित कार्यान्वयनों पर विचार करें :

void invite(String emailAddressString) {
  invite(EmailAddress.parse(emailAddressString));
}
void invite(EmailAddress emailAddress) {
  ...
}
void invite(User user) {
  invite(user.getEmailAddress());
}

एक में पासिंग Stringजहां एक में पास करना चाहिए EmailAddressत्रुटिपूर्ण होती, क्योंकि सभी तार ईमेल पते हैं। EmailAddressवर्ग बेहतर शब्दार्थ विधि के व्यवहार से मेल खाता है। हालाँकि इसमें पास Userहोना भी त्रुटिपूर्ण है क्योंकि पृथ्वी पर EmailInviterउपयोगकर्ताओं को आमंत्रित करने के लिए सीमित क्यों होना चाहिए ? व्यवसायों के बारे में क्या? यदि आप किसी फ़ाइल या कमांड लाइन से ईमेल पते पढ़ रहे हैं और वे उपयोगकर्ताओं से संबद्ध नहीं हैं तो क्या होगा? ईमेल की सूची? सूची चलती जाती है।

कुछ मार्गदर्शन संकेत हैं जिनका उपयोग आप यहां मार्गदर्शन के लिए कर सकते हैं। यदि आप किसी साधारण मान प्रकार का उपयोग कर रहे हैं Stringया intनहीं, लेकिन सभी तार या स्याही मान्य नहीं हैं या उनके बारे में कुछ "विशेष" है, तो आपको अधिक सार्थक प्रकार का उपयोग करना चाहिए। यदि आप किसी ऑब्जेक्ट का उपयोग कर रहे हैं और केवल एक चीज जो आप कर रहे हैं वह एक कॉल्टर है, तो आपको ऑब्जेक्ट को सीधे बदले में गेटर में पास करना चाहिए। ये दिशानिर्देश न तो कठिन हैं और न ही तेज़ हैं, लेकिन कुछ दिशानिर्देश हैं।


0

स्वच्छ संहिता में यथासंभव कम तर्क देने की सिफारिश की गई है, जिसका अर्थ है कि वस्तु आमतौर पर बेहतर दृष्टिकोण होगी और मुझे लगता है कि यह कुछ समझ में आता है। इसलिये

insertIntoDatabase(new Account(id) , new Otherthing(id, "Value"));

से अधिक पठनीय कॉल है

insertIntoDatabase(myAccount.getId(), myOtherthing.getId(), myOtherthing.getValue() );

वहाँ सहमत नहीं हो सकते। दोनों पर्यायवाची नहीं हैं। एक विधि में उन्हें पास करने के लिए सिर्फ 2 नए ऑब्जेक्ट इंस्टेंस बनाना अच्छा नहीं है। मैं आपके किसी भी विकल्प के बजाय InsertIntoDatabase (myAccount, myOtherthing) का उपयोग करूंगा।
jwenting

0

ऑब्जेक्ट के चारों ओर से गुजरें, न कि इसका घटक राज्य। यह एनकैप्सुलेशन और डेटा छिपाने के ऑब्जेक्ट-ओरिएंटेड सिद्धांतों का समर्थन करता है। किसी वस्तु के सराय को विभिन्न विधि इंटरफेसों में उजागर करना जहां यह आवश्यक नहीं है कि कोर OOP सिद्धांतों का उल्लंघन करता है।

यदि आप खेतों को बदलते हैं तो क्या होता है Otherthing? हो सकता है कि आप एक प्रकार बदलें, एक फ़ील्ड जोड़ें, या एक फ़ील्ड निकालें। अब आपके प्रश्न में उल्लिखित सभी तरीकों को अपडेट करने की आवश्यकता है। यदि आप ऑब्जेक्ट के चारों ओर से गुजरते हैं, तो कोई इंटरफ़ेस परिवर्तन नहीं हैं।

किसी वस्तु पर फ़ील्ड्स को स्वीकार करने की विधि लिखने के लिए एकमात्र समय तब होता है जब आप ऑब्जेक्ट को पुनः प्राप्त करने के लिए एक विधि लिखते हैं:

public User getUser(String primaryKey) {
  return ...;
}

उस कॉल को करने के बिंदु पर, कॉलिंग कोड का अभी तक ऑब्जेक्ट के लिए संदर्भ नहीं है क्योंकि ऑब्जेक्ट को प्राप्त करने के लिए उस पद्धति को कॉल करने का बिंदु है।


1
"यदि आप खेतों को बदलते हैं तो क्या होता है Otherthing?" (1) यह खुले / बंद सिद्धांत का उल्लंघन होगा। (२) यदि आप पूरे ऑब्जेक्ट को पास करते हैं, तो भी उसके भीतर का कोड तब उस ऑब्जेक्ट के सदस्यों तक पहुंचता है (और यदि ऐसा नहीं है, तो ऑब्जेक्ट को पास क्यों?) अभी भी टूट जाएगा ...
डेविड अरनो

@DavidArno मेरे उत्तर की बात यह नहीं है कि कुछ भी नहीं टूटेगा, लेकिन कम टूट जाएगा। या तो पहले पैराग्राफ को मत भूलना: चाहे जो भी टूट जाए, ऑब्जेक्ट के इंटरफ़ेस का उपयोग करके किसी ऑब्जेक्ट की आंतरिक स्थिति को अमूर्त किया जाना चाहिए। इसकी आंतरिक स्थिति के आसपास गुजरना OOP सिद्धांतों का उल्लंघन है।

0

एक स्थिरता के दृष्टिकोण से, तर्क को अनिवार्य रूप से संकलक स्तर पर एक दूसरे से स्पष्ट रूप से अलग होना चाहिए।

// this has exactly one way to call it
insertIntoDatabase(Account ..., Otherthing ...)

// the parameter order can be confused in practice
insertIntoDatabase(long ..., long ...)

पहला डिज़ाइन बग्स का जल्द पता लगाने की ओर ले जाता है। दूसरा डिज़ाइन सूक्ष्म रनटाइम मुद्दों को जन्म दे सकता है जो परीक्षण में दिखाई नहीं देते हैं। इसलिए पहले डिजाइन को प्राथमिकता दी जानी है।


0

दो में से, मेरी प्राथमिकता पहली विधि है:

function insertIntoDatabase(Account account, Otherthing thing) { database.insertMethod(account.getId(), thing.getId(), thing.getSomeValue()); }

कारण यह है कि परिवर्तन सड़क के नीचे या तो ऑब्जेक्ट के लिए किए गए परिवर्तन, जब तक कि परिवर्तन उन गेटर्स को संरक्षित करते हैं ताकि परिवर्तन ऑब्जेक्ट के बाहर पारदर्शी हो, तो आपके पास बदलने के लिए कम कोड और परीक्षण और एप्लिकेशन को बाधित करने की कम संभावना है।

यह सिर्फ मेरी विचार प्रक्रिया है, ज्यादातर इस बात पर आधारित है कि मुझे इस प्रकृति की चीजों को कैसे काम करना और संरचना करना पसंद है और जो लंबे समय में काफी प्रबंधनीय और रखरखाव योग्य साबित होती हैं।

मैं नामकरण सम्मेलनों में नहीं जा रहा हूं, लेकिन यह बताऊंगा कि हालांकि इस पद्धति में "डेटाबेस" शब्द है, लेकिन भंडारण तंत्र सड़क को बदल सकता है। दिखाए गए कोड से, फ़ंक्शन को डेटाबेस स्टोरेज प्लेटफ़ॉर्म पर उपयोग किए जा रहे कुछ भी बांधना नहीं है - या भले ही वह डेटाबेस हो। हमने सिर्फ इसलिए मान लिया क्योंकि यह नाम में है। फिर, यह मानते हुए कि उन गेटर्स को हमेशा संरक्षित रखा जाता है, इन वस्तुओं को कैसे / कहाँ संग्रहीत किया जाता है, यह बदलना आसान होगा।

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

जैसे ही कोड अब खड़ा होता है, सवाल यह होता है कि "यह कार्य कहाँ और कैसे होना चाहिए?" क्या यह अकाउंट का हिस्सा है, या OtherThing? यह कहाँ जाता है?

मुझे लगता है कि पहले से ही एक तीसरा ऑब्जेक्ट "डेटाबेस" है, और मैं इस फ़ंक्शन को उस ऑब्जेक्ट में डालने की दिशा में झुकाव कर रहा हूं, और फिर यह हो जाता है कि ऑब्जेक्ट एक खाता और एक अन्य को संभालने में सक्षम होने के लिए काम करते हैं, रूपांतरित करते हैं, और फिर परिणाम भी जारी रखते हैं ।

यदि आप के रूप में दूर जाना था कि 3 वस्तु एक वस्तु-संबंधपरक मानचित्रण (ORM) पैटर्न, सभी बेहतर के अनुरूप है। यह कोड के साथ काम करने वाले किसी के लिए भी बहुत स्पष्ट हो जाएगा "आह, यह वह जगह है जहाँ खाता और OtherThing एक साथ तोड़े जाते हैं और बने रहते हैं"।

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

मैं डिजाइन को बनाए रखने के लिए गोली मारूंगा ताकि कोई भी एक खाता, अन्य, या तीसरी ओआरएम वस्तु को अन्य तीन को भी बदले बिना बदला जा सके। जब तक कोई अच्छा कारण न हो, मैं चाहता हूं कि अकाउंट और अदरंग स्वतंत्र रहें और एक-दूसरे के आंतरिक कामकाज और संरचनाओं को न जानें।

बेशक, अगर मुझे पूरा संदर्भ पता था कि यह होने जा रहा है, तो मैं अपने विचारों को पूरी तरह से बदल सकता हूं। फिर, यह सिर्फ यह है कि जब मैं इस तरह की चीजों को देखता हूं, तो मैं कैसा लगता हूं।


0

दोनों दृष्टिकोणों के अपने-अपने पक्ष और विपक्ष हैं। परिदृश्य में क्या बेहतर है यह हाथ में उपयोग-मामले पर बहुत कुछ निर्भर करता है।


प्रो मल्टीपल परम, कॉन ऑब्जेक्ट संदर्भ:

  • कॉलर एक विशिष्ट वर्ग के लिए बाध्य नहीं है , यह विभिन्न स्रोतों से मूल्यों को पूरी तरह से पारित कर सकता है
  • ऑब्जेक्ट राज्य विधि निष्पादन के अंदर अप्रत्याशित रूप से संशोधित होने से सुरक्षित है

प्रो वस्तु संदर्भ:

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

इसलिए, क्या उपयोग किया जाना चाहिए और कब उपयोग के मामलों पर बहुत कुछ निर्भर करता है

  1. व्यक्तिगत पैरामीटर पास करें: सामान्य तौर पर, यदि विधि का ऑब्जेक्ट प्रकार से कोई लेना-देना नहीं है, तो व्यक्तिगत पैरामीटर सूची को पास करना बेहतर है ताकि यह व्यापक दर्शकों पर लागू हो।
  2. नए मॉडल ऑब्जेक्ट का परिचय दें: यदि पैरामीटर की सूची बड़ी हो जाती है (3 से अधिक), तो नया एपीआई ऑब्जेक्ट (बिल्डर पैटर्न पसंदीदा) से संबंधित मॉडल को पेश करना बेहतर है।
  3. पास ऑब्जेक्ट रेफरेंस: यदि विधि डोमेन ऑब्जेक्ट्स से संबंधित है, तो ऑब्जेक्ट रेफरेंस पास करने के लिए इसकी स्थिरता और पठनीयता के दृष्टिकोण से बेहतर है।

0

एक तरफ आपके पास एक खाता और एक अन्य वस्तु है। दूसरी तरफ, आपके पास एक डेटाबेस में एक मूल्य डालने की क्षमता है, एक खाते की आईडी और दूसरी चीज़ की आईडी को देखते हुए। यही दो चीजें हैं।

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

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

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

C ++ में, आपके पास दो आईडी प्लस मान लेने की एक विधि हो सकती है, और एक इनलाइन विधि खाता और अन्य चीजें ले सकती है, इसलिए आपके पास शून्य ओवरहेड के साथ दोनों तरीके हैं।

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