2012-05-09 13 views
7

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

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

मुख्य विंडो के पीछे कोड में मैंने एक टेक्स्ट बॉक्स और एक बटन डाला। जब खिड़की लोड होती है तो यह व्यक्ति x नाम फ़ील्ड का वर्तमान मान दिखाती है। जब बटन क्लिक किया जाता है, तो x.PersonAddText विधि को कॉल किया जाता है। वर्तमान में इस उदाहरण में युग्मन 8 पर गणना की गई है। बटन के लिए 3 के साथ ईवेंट और विंडो लोड किए गए ईवेंट के लिए 3।

क्या कोई तरीका है, इस उदाहरण का उपयोग करके हम इसे या तो दोनों के लिए इससे कम कर सकते हैं।

नीचे अपने सभी कोड है:

मेरे व्यक्ति कक्षा:

public class Person 
{ 
    //Fields 
    private string name; 

    //Properties 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    //Constructors 
    public Person() 
    { 
     name = "joe"; 
    } 

    //Methods 
    public string PersonAddText(string text) 
    { 
     return name += " - " + text; 
    } 

    //Interfaces (or additional code below here please to aid understanding) 
} 

मेरे कोड के पीछे:

Person x = new Person(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     txtname.Text = x.Name; 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     txtname.Text = x.PersonAddText(txtname.Text); 
     txtname.Text = x.Name; 
    } 

मेरे सरल XAML:

<Grid> 
    <TextBox Name="txtname" Margin="12,12,12,0" Height="23" VerticalAlignment="Top" /> 
    <Button Content="Add Text" Margin="12,41,12,0" Name="button1" VerticalAlignment="Top" Click="button1_Click" /> 
</Grid> 

मैं कर रहा हूँ बड़ी कठिनाई unde इंटरनेट के चारों ओर ट्यूटोरियल को समझाने के लिए यह समझाओ।

  • सेवा लोकेटर
  • निर्भरता इंजेक्शन
  • उलट: मैं वहाँ यह करने के लिए 3 तरीके हैं जो देखते हैं से (यह संभव हो तो, इन तीनों का एक उदाहरण के लिए परिवर्तित ऊपर मेरी कोड के लिए अच्छा होगा) नियंत्रण (आईओसी)

article सामान मैं पढ़ लिया है समझाने का उत्कृष्ट है, लेकिन के रूप में वह डेटाबेस कनेक्शन तार के साथ वीबी और ASP.Net उपयोग कर रहा है उदाहरण मेरे लिए प्रासंगिक नहीं हैं। यह पूरी तरह से विपरीत है जो मुझे चाहिए, और मैं इस बारे में सोचना नहीं चाहता कि कोड का अनुवाद कैसे करें, अवधारणाओं को सीखते हुए, और इस बारे में भी सोचें कि इसे प्रासंगिक कुछ कैसे लागू करें। हालांकि उदाहरण अच्छा है, यह बहुत अधिक है, और मैं वास्तव में किसी भी अतिरिक्त मदद की सराहना करता हूं।

इतिहास संपादित करें: वर्तनी वर्तनी। मेरे प्रश्न को स्पष्ट करने के लिए निम्नलिखित जोड़ा गया:

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

the article I refrenced above पर एक लिंक जोड़ा गया।

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

public interface IPerson 
{ 
    string Name { get; set; } 
    string PersonAddText(string text); 
} 

public class Person : IPerson 
{ 
    //The code from the person class above 
} 

कैसे मैं अब इस MainWindow कोड में पीछे प्रयोग करते हैं: अब तक मैं अब क्या मिल गया है निम्नलिखित है?मैं अनुमान लगा रहा हूँ मैं

IPerson x = new Person(); 

साथ

Person x = new Person(); 

बदलना चाहिए यह सही है, और यदि हां, वहाँ कुछ और मैं क्या करने की जरूरत है। कारण मैं पूछता हूं क्योंकि मुझे अभी भी दृश्य स्टूडियो द्वारा रिपोर्ट किए गए कोड युग्मन आंकड़ों में कोई कमी नहीं दिखाई दे रही है (वास्तव में, यह इसे मुख्य विंडो कोड पर 1 तक बढ़ा देता है)।

+0

क्या _exactly_ आप समझ में नहीं आता? आपको किस अवधारणा के साथ कठिनाइयों का सामना करना पड़ रहा है? – Oded

+0

मुझे पता है कि सिद्धांत में कूपलिंग और एकजुटता का क्या अर्थ है। लेकिन मैं समझ नहीं पा रहा हूं कि इसे कैसे कोड करें। खासकर जब हमने कभी कॉलेज में इंटरफेस को कवर नहीं किया (हाँ, मुझे पता है, महान कॉलेज)। मैं इंटरफ़ेस भी समझता हूं, लेकिन मुझे नहीं पता कि कूपलिंग कम करने के लिए उनका उपयोग कैसे किया जाए। –

उत्तर

3

संपादित

मुझे खुशी है कि मेरा उत्तर एक सा मदद की हूँ, मुझे यह थोड़ा आगे अपडेट करने दें।

Person x = new Person(); 

IPerson x = new Person(); 

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

साइड नोट

मैं विचार कर रहा सिफारिश करेंगे आलसी लोड x व्यक्ति, और यह भी एक अधिक पहचानने योग्य नाम के साथ एक संपत्ति का उपयोग कर। N.B. यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन यह सिर्फ एक सुझाव है। :)

private IPerson _CurrentPerson = null; 
private IPerson CurrentPerson 
{ 
    get 
    { 
     if (this._CurrentPerson == null) 
     { 
      this._CurrentPerson = new Person(); 
     } 
     return this._CurrentPerson 
    } 
    set 
    { 
     this._CurrentPerson = value; 
    } 
} 

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

public interface IPerson 
{ 
    string Name { get; set; } 
    string PersonAddText(string text); 
} 

public class Person : IPerson 
{ 
    // your code here 
} 

, अपने मुख्य विधि कॉल के अंतर्गत, बजाय स्पष्ट रूप से एक Person वस्तु का उपयोग करने के लिए, आप एक का उपयोग करेगा:

अपने उपरोक्त उदाहरण में, तुम इतनी तरह अपने व्यक्ति वर्ग, शायद कुछ इंटरफेस चाहते हैं एक ऑब्जेक्ट का उदाहरण जो इंटरफ़ेस IPerson लागू करता है। इंटरफेस और ऑब्जेक्ट का "हुकिंग" विभिन्न विभिन्न पुस्तकालयों द्वारा हासिल किया जा सकता है जो आपकी निर्भरताओं को स्थापित करने में मदद करेंगे। मेरे अनुभव में मैंने StructureMap और Microsoft's Enterprise Library का उपयोग किया है। वे सेट अप करने के लिए बारीकियों थोड़ा हो सकता है, लेकिन एक बार वे कर रहे हैं, तो आप ऐसा तरह कुछ करने के लिए सक्षम हो जाएगा ...

public void MainMethod_InInterfaceLayer() 
{ 
    // container is an instance of UnityContainer 
    Person newPerson = container.Resolve<IPerson>(); 
} 

मैं इस एक पूरा जवाब ins't पता है, लेकिन उम्मीद है कि यह थोड़ा सा मदद करेंगे।:)

+0

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

+1

मैंने अपना जवाब अपडेट कर दिया है। उम्मीद है कि, ओडेड के जवाब के संयोजन के साथ, यह वही होना चाहिए जो आप खोज रहे हैं। – Richard

+0

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

2

आप एक IPerson इंटरफेस और कई कार्यान्वयन (Person, Student, Teacher आदि) है और आप कुछ कोड है कि बस एक IPerson पर काम करने की जरूरत है है कहो।

होने:

IPerson x = new Person(); 

अपने कोड में पीछे दृढ़ता से जोड़ों यह Person वर्ग के लिए।

कक्षा के अंदर बनाने के बजाय निर्भरताएं बाहर से आने से नियंत्रण में उलझन में आती है।

यह आमतौर पर निर्भरता इंजेक्शन का उपयोग करके हासिल किया जाता है - एक IPerson कक्षा को सीधे बनाने के बजाय वर्ग में पारित किया जा रहा है। आप इसे कन्स्ट्रक्टर (कन्स्ट्रक्टर इंजेक्शन) या एक संपत्ति (संपत्ति इंजेक्शन) के रूप में एक उदाहरण पास करके कर सकते हैं।

सेवा लोकेटर बिना किसी कोडिंग के निर्भरता प्राप्त करने का एक और तरीका है - पैटर्न एक प्रकार/इंटरफ़ेस के लिए एक उदाहरण "रेखांकित" करता है।

कैसे एक वर्ग के लिए एक निर्भरता सुई का एक उदाहरण:

public class MyClass 
{ 
    IPerson person; 

    public MyClass(IPerson p) 
    { 
    person = p; // injected an instance of IPerson to MyClass 
    } 

    // can now use person in any method of the class, or pass it around: 

    public void MyMethod() 
    { 
    string name = person.Name; 
    } 
} 
+0

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

+1

@ फ्रैंकिसरोडर्स - 'आईपर्सन' के किसी भी कार्यान्वयन से कक्षा 'माय क्लास' को कैसे डिस्प्ले किया गया है, इसका एक उदाहरण जोड़ा गया है, इसलिए _any_ कार्यान्वयनकर्ता का उपयोग किया जा सकता है। कन्स्ट्रक्टर इंजेक्शन का एक केस भी दिखा रहा है। – Oded

0

मान लीजिए आप एक व्यक्ति वर्ग है जो अपने आप डेटाबेस से लोड कर सकते हैं है, बदल गया है और ईमेल भेजने के लिए जब वह मर गया मिलता है।

class Person 
{ 
    ... 
    void LoadUsingId(int id); 
    void HaveDiedWillMail(); 
    void SetFirstName(string name); 
    ... 
} 

आप यहां क्या देख सकते हैं कि यह व्यक्ति वास्तव में तीन चीजें कर रहा है (कम से कम!)।

यह जानता है कि डेटाबेस को स्वयं लोड करने के लिए कैसे बात करें। यह जानता है कि ईमेल कैसे भेजना है। यह स्वयं बदल सकता है।

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

class Person 
{ 
    ... 
    void LoadUsingId(PersonRepository person); 
    void HaveDiedWillMail(IMailer mailer); 
    void SetFirstName(string name); 
    ... 
} 

इस प्रदूषित उदाहरण में, व्यक्ति को पता नहीं है कि डेटाबेस से कुछ कैसे लोड किया जाए। इस तथ्य को अनदेखा करते हुए कि -लोडिंग- कुछ ऐसा है जो आपको भी कम करना चाहिए। मेल भेजने को भी हटा दिया गया है, क्योंकि आप Person.HaveDiedWillMail बताते हैं कि आप किसी विशेष मेलर (IMailer mailer) का उपयोग करना चाहते हैं।

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

+0

मैं इस बात से असहमत हूं कि एक ऑब्जेक्ट (मॉडल) को डेटाबेस से खुद को लोड करना चाहिए, यहां तक ​​कि एक कमजोर युग्मित तरीके से भी। एक मॉडल * एक काम करना चाहिए *: एक वास्तविक वस्तु का प्रतिनिधित्व करें। डेटाबेस से लोड करना किसी अन्य ऑब्जेक्ट का काम है, जो * एक काम करेगा *: डेटाबेस से डेटा लोड करें। वास्तव में, मॉडल और डेटाबेस के बीच में दो परतें बहुत अच्छी होंगी। –

+0

मैं भी आपसे सहमत हूं। लेकिन मैं यहाँ सब कुछ समझाने की कोशिश नहीं कर रहा हूं या यहां तक ​​कि समझदार क्या है ... लेकिन decoupling। – Jaapjan

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