क्या हमें कस्टम ऑब्जेक्ट्स को पैरामीटर के रूप में बचना चाहिए?


49

मान लीजिए कि मेरे पास एक कस्टम ऑब्जेक्ट है, छात्र :

public class Student{
    public int _id;
    public String name;
    public int age;
    public float score;
}

और एक वर्ग, विंडो , जिसका उपयोग किसी छात्र की जानकारी दिखाने के लिए किया जाता है :

public class Window{
    public void showInfo(Student student);
}

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

public void showInfo(int _id, String name, int age, float score);

ताकि व्यक्तिगत रूप से विंडो का परीक्षण करना आसान हो :

showInfo(123, "abc", 45, 6.7);

लेकिन मुझे लगा कि संशोधित संस्करण में एक और समस्या है:

  1. छात्र को संशोधित करें (जैसे: नई संपत्तियाँ जोड़ें) को शो-इन की विधि-हस्ताक्षर को संशोधित करने की आवश्यकता है

  2. यदि छात्र के पास कई गुण हैं, तो छात्र का विधि-हस्ताक्षर बहुत लंबा होगा।

तो, कस्टम ऑब्जेक्ट्स को पैरामीटर के रूप में उपयोग करना या ऑब्जेक्ट में प्रत्येक प्रॉपर्टी को पैरामीटर के रूप में स्वीकार करना, जो एक अधिक रखरखाव योग्य है?


40
और आपके 'सुधार' के showInfoलिए एक वास्तविक स्ट्रिंग, एक वास्तविक फ्लोट और दो वास्तविक इनट्स की आवश्यकता होती है। एक वास्तविक Stringवस्तु प्रदान करने से बेहतर कैसे एक वास्तविक वस्तु प्रदान कर रहा Studentहै?
बार्ट वैन इनगेन शेनॉ

28
सीधे मापदंडों को पारित करने के साथ एक बड़ी समस्या: अब आपके पास दो intपैरामीटर हैं। कॉल साइट से, कोई सत्यापन नहीं है कि आप वास्तव में उन्हें सही क्रम में पास कर रहे हैं। क्या होगा अगर आप स्वैप idऔर age, या firstNameऔर lastName? आप विफलता के एक संभावित बिंदु का परिचय दे रहे हैं, जिसका पता लगाना बहुत कठिन हो सकता है, जब तक कि यह आपके चेहरे पर न उड़ जाए, और आप इसे हर कॉल साइट पर जोड़ रहे हैं ।
क्रिस हेस

38
@ChrisHayes आह, पुरानी showForm(bool, bool, bool, bool, int)विधि - मैं उन लोगों से प्यार करता हूं ...
बोरिस द स्पाइडर

3
@ क्रिसहेस कम से कम इसके जेएस नहीं ...
जेन्स स्काउडर

2
परीक्षणों की एक अविकसित संपत्ति: यदि परीक्षणों में अपनी स्वयं की वस्तुओं को बनाना / उपयोग करना कठिन है , तो आपका एपीआई संभवतः कुछ काम का उपयोग कर सकता है :)
Eevee

जवाबों:


131

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

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


14
यदि नई वस्तु वास्तव में एक तार्किक समूहन नहीं है तो आप चेतावनी दे सकते हैं कि आप स्वयं को परेशानी में डाल सकते हैं। हर पैरामीटर को एक ही ऑब्जेक्ट में सेट करने का प्रयास न करें; केस के आधार पर केस तय करें। प्रश्न में उदाहरण स्पष्ट रूप से इसके लिए एक अच्छा उम्मीदवार होने के लिए लगता है। Studentसमूहीकरण समझ में आता है और एप्लिकेशन के अन्य क्षेत्रों में पैदा होने की संभावना है।
jpmc26

यदि आपके पास पहले से ही वस्तु है, तो Studentयह कहना , उदाहरण के लिए , यह एक संपूर्ण वस्तु होगी
abuzittin gillifirca

4
साथ ही लॉ ऑफ डेमेटर को याद करें । वहाँ एक संतुलन मारा जा सकता है, लेकिन tldr ऐसा नहीं है a.b.cअगर आपकी विधि लेता है a। यदि आपकी विधि उस बिंदु पर पहुंच जाती है, जहां आपको लगभग 4 से अधिक पैरामीटर या संपत्ति के परिग्रहण के 2 स्तरों से अधिक की आवश्यकता होती है, तो संभवत: इसे समाप्त करने की आवश्यकता होती है। यह भी ध्यान दें कि यह एक दिशानिर्देश है - अन्य सभी दिशानिर्देशों की तरह, इसके लिए उपयोगकर्ता के विवेक की आवश्यकता होती है। आँख बंद करके इसका पालन न करें।
डेन पेंट्री

7
मुझे इस उत्तर का पहला वाक्य अत्यधिक कठिन लगा।
हेलिकेयर

5
@Qwerky मैं बहुत दृढ़ता से असहमत हूँ। छात्र वास्तव में वस्तु ग्राफ में एक पत्ते की तरह लगता है (शायद नाम, DateOfBirth आदि जैसे अन्य तुच्छ वस्तुओं को छोड़कर), केवल एक छात्र के राज्य के लिए एक कंटेनर। ऐसा कोई कारण नहीं है कि एक छात्र को निर्माण करने के लिए कठिन होना चाहिए, क्योंकि यह एक रिकॉर्ड प्रकार होना चाहिए। एक छात्र के लिए टेस्ट डबल्स बनाना कुछ फैंसी अलगाव ढांचे पर परीक्षणों और / या भारी निर्भरता को बनाए रखने के लिए एक नुस्खा की तरह लगता है।
सारा

26

आप कहते हैं

व्यक्तिगत रूप से परीक्षण करना काफी आसान नहीं है, क्योंकि इसे फ़ंक्शन को कॉल करने के लिए एक वास्तविक छात्र ऑब्जेक्ट की आवश्यकता होती है

लेकिन आप अपनी विंडो में पास होने के लिए सिर्फ एक छात्र ऑब्जेक्ट बना सकते हैं:

showInfo(new Student(123,"abc",45,6.7));

यह कॉल करने के लिए बहुत अधिक जटिल नहीं लगता है।


7
समस्या तब आती है जब Studentएक को संदर्भित करता है University, जो कई Facultyएस और Campusएस के साथ है, Professorएस और Buildingएस के साथ, जिनमें से कोई भी showInfoवास्तव में उपयोग नहीं करता है, लेकिन आपने किसी भी इंटरफ़ेस को परिभाषित नहीं किया है जो परीक्षणों को "जानने" और केवल संबंधित छात्र को आपूर्ति करने की अनुमति देता है। डेटा, पूरे संगठन के निर्माण के बिना। उदाहरण Studentएक सादा डेटा ऑब्जेक्ट है और, जैसा कि आप कहते हैं, परीक्षणों को इसके साथ काम करने में खुशी होनी चाहिए।
स्टीव जेसोप

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

1
@abuzittingillifirca, "ऑब्जेक्ट मदर" एक समाधान है, आपके छात्र की वस्तु भी जटिल हो सकती है। यह बेहतर हो सकता है कि केवल विश्वविद्यालय के पास हो, और एक सेवा (निर्भरता इंजेक्शन का उपयोग करके) जो विश्वविद्यालय के विश्वविद्यालय से एक वस्तु दे।
इयान

12
यदि छात्र बहुत जटिल है या इसे केवल नकल करना शुरू करना कठिन है। परीक्षण मॉकिटो या अन्य भाषाओं के समकक्ष जैसे फ्रेमवर्क के साथ अधिक शक्तिशाली है।
बोरबज़

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

22

आम आदमी की शर्तों में:

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

संपादित करें:

जैसा कि @ Tom.Bowen89 बताता है कि शोइंफो विधि का परीक्षण करने के लिए यह अधिक जटिल नहीं है:

showInfo(new Student(8812372,"Peter Parker",16,8.9));

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

3

कोड पूरा करने में स्टीव मैककोनेल ने इस मुद्दे को संबोधित किया, गुणों का उपयोग करने के बजाय वस्तुओं में गुजरने के लाभों और कमियों पर चर्चा की।

यदि मुझे कुछ विवरण गलत मिले तो मुझे माफ़ कर दें, मैं स्मृति से काम कर रहा हूँ क्योंकि मुझे पुस्तक तक पहुँचते हुए एक वर्ष से अधिक हो गया है:

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

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

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


7
मेरे पास कोड पूरा है 2. इसमें एक पूरा पृष्ठ इस मुद्दे को समर्पित है। निष्कर्ष यह है कि पैरामीटर सही अमूर्त स्तर पर होना चाहिए। कभी-कभी एक संपूर्ण वस्तु को पारित करने की आवश्यकता होती है, कभी-कभी केवल व्यक्तिगत विशेषताएं।
से आया

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

2

यदि आप संपूर्ण ऑब्जेक्ट पास करते हैं तो परीक्षण लिखना और पढ़ना बहुत आसान है:

public class AStudentView {
    @Test 
    public void displays_failing_grade_warning_when_a_student_with_a_failing_grade_is_shown() {
        StudentView view = aStudentView();
        view.show(aStudent().withAFailingGrade().build());
        Assert.that(view, displaysFailingGradeWarning());
    }

    private Matcher<StudentView> displaysFailingGradeWarning() {
        ...
    }
}

तुलना के लिए,

view.show(aStudent().withAFailingGrade().build());

लाइन लिखी जा सकती है, यदि आप मानों को अलग से पास करते हैं, जैसे:

showAStudentWithAFailingGrade(view);

जहां वास्तविक विधि कॉल कहीं दफन है

private showAStudentWithAFailingGrade(StudentView view) {
    int someId = .....
    String someName = .....
    int someAge = .....
    // why have been I peeking and poking values I don't care about
    decimal aFailingGrade = .....
    view.show(someId, someName, someAge, aFailingGrade);
}

इस बिंदु पर होना, कि आप परीक्षण में वास्तविक विधि कॉल नहीं कर सकते हैं एक संकेत है कि आप एपीआई खराब है।


1

आपको पास करना चाहिए जो समझ में आता है, कुछ विचार:

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

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

मैं सबसे अधिक इच्छुक रहूंगा कि मुख्य वस्तु को पारित किया जाए - क्योंकि मैं यह कैसे कोड आसानी से समझा रहा हूं कि यह फ़ंक्शन क्या कर रहा है।


1

इसके चारों ओर एक सामान्य मार्ग दो प्रक्रियाओं के बीच एक इंटरफ़ेस सम्मिलित करना है।

public class Student {

    public int id;
    public String name;
    public int age;
    public float score;
}

interface HasInfo {
    public String getInfo();
}

public class StudentInfo implements HasInfo {
    final Student student;

    public StudentInfo(Student student) {
        this.student = student;
    }

    @Override
    public String getInfo() {
        return student.name;
    }

}

public class Window {

    public void showInfo(HasInfo info) {

    }
}

यह कभी-कभी थोड़ा गड़बड़ हो जाता है, लेकिन अगर आप एक आंतरिक वर्ग का उपयोग करते हैं तो चीजें जावा में थोड़ा टिडियर हो जाती हैं।

interface HasInfo {
    public String getInfo();
}

public class Student {

    public int id;
    public String name;
    public int age;
    public float score;

    public HasInfo getInfo() {
        return new HasInfo () {
            @Override
            public String getInfo() {
                return name;
            }

        };
    }
}

तब आप Windowकेवल एक नकली HasInfoवस्तु देकर कक्षा का परीक्षण कर सकते हैं ।

मुझे संदेह है कि यह डेकोरेटर पैटर्न का एक उदाहरण है ।

जोड़ा गया

कोड की सादगी के कारण कुछ भ्रम होने लगता है। यहां एक और उदाहरण है जो तकनीक का बेहतर प्रदर्शन कर सकता है।

interface Drawable {

    public void Draw(Pane pane);
}

/**
 * Student knows nothing about Window or Drawable.
 */
public class Student {

    public int id;
    public String name;
    public int age;
    public float score;
}

/**
 * DrawsStudents knows about both Students and Drawable (but not Window)
 */
public class DrawsStudents implements Drawable {

    private final Student subject;

    public DrawsStudents(Student subject) {
        this.subject = subject;
    }

    @Override
    public void Draw(Pane pane) {
        // Draw a Student on a Pane
    }

}

/**
 * Window only knows about Drawables.
 */
public class Window {

    public void showInfo(Drawable info) {

    }
}

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

@kai - वापसी प्रकार के लिए Studentऔर Stringयहाँ का उपयोग पूरी तरह से प्रदर्शन के लिए है। ड्राइंग करने getInfoके Paneलिए आकर्षित करने के लिए इस तरह के अतिरिक्त पैरामीटर होने की संभावना होगी । यहाँ अवधारणा कार्यात्मक घटकों को मूल वस्तु के सज्जाकार के रूप में पारित करना है
ओल्डकर्मुडीनगर

उस स्थिति में आप छात्र इकाई को अपने UI ढांचे से कसकर जोड़ देंगे, और भी बुरा लगता है ...
सारा

1
@kai - इसके विपरीत। मेरा UI केवल HasInfoवस्तुओं के बारे में जानता है। Studentएक होना जानता है।
ओल्डकर्मुडीनगर

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

1

आपके पास पहले से ही बहुत अच्छे उत्तर हैं, लेकिन यहां कुछ और सुझाव दिए गए हैं जो आपको वैकल्पिक समाधान देखने की अनुमति दे सकते हैं:

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

  • अपने मॉडल ऑब्जेक्ट के प्रासंगिक भागों को डेटा ट्रांसफर ऑब्जेक्ट में स्थानांतरित करना आपके मॉडल के बहुत जटिल होने पर इंटरफेसिंग के लिए एक उपयोगी दृष्टिकोण है।

  • हो सकता है कि आपका छात्र इंटरफ़ेस अलगाव सिद्धांत का उल्लंघन करता हो। यदि हां, तो इसे कई इंटरफेस में विभाजित करना फायदेमंद हो सकता है जो इसके साथ काम करना आसान है।

  • आलसी लोडिंग बड़े ऑब्जेक्ट ग्राफ के निर्माण को आसान बना सकता है।


0

यह वास्तव में एक सभ्य सवाल है। यहां वास्तविक मुद्दा सामान्य शब्द "ऑब्जेक्ट" का उपयोग है, जो थोड़ा अस्पष्ट हो सकता है।

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

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

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


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

कक्षाएं और संरचनाएं बहुत अलग हैं। एक मूल्य द्वारा पारित हो जाता है (यह एक हो जाता है प्राप्त विधि अर्थ प्रतिलिपि ) और अन्य (रिसीवर सिर्फ मूल के सूचक हो जाता है) संदर्भ द्वारा पारित कर दिया है। इस अंतर को न समझना खतरनाक है।
RubberDuck

@kai मुझे लगता है कि एक संदर्भ पारित करना महंगा नहीं है। मैं यह कह रहा हूं कि एक ऐसा फंक्शन तैयार करना है जिसमें उस वर्ग की निर्भरता, उसके तरीके आदि के आधार पर एक पूर्ण श्रेणी के उदाहरण की आवश्यकता हो।
दोपहर का भोजन 1717

मैं व्यक्तिगत रूप से केवल उन सीमाओं के बारे में कुछ भी मज़ाक करने के खिलाफ हूं, जो बाहरी प्रणालियों (फ़ाइल / नेटवर्क IO) या गैर-नियतात्मक (जैसे यादृच्छिक, सिस्टम समय-आधारित, आदि) का उपयोग करने वाली सीमाओं को छोड़कर। यदि मैं जिस कक्षा का परीक्षण कर रहा हूं, उसमें एक निर्भरता है जो वर्तमान विशेषता के परीक्षण के लिए प्रासंगिक नहीं है, मैं जहां संभव हो वहां बस पास करना पसंद करता हूं। लेकिन अगर आप एक ऐसी विधि का परीक्षण कर रहे हैं जो एक पैरामीटर ऑब्जेक्ट लेता है, अगर उस ऑब्जेक्ट पर निर्भरता का एक गुच्छा है जो मुझे समग्र डिजाइन के बारे में चिंतित होगा। ऐसी वस्तुओं को हल्का होना चाहिए।
सारा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.