2010-04-15 8 views
10

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

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

template <typename Iter> 
double mean(Iter first, Iter last) 
{ 
    double sum = 0; 
    size_t number = 0; 
    while (first != last) 
    { 
     sum += *(first++); 
     ++number; 
    } 
    return sum/number; 
}; 

इस है (अर्थात, बजाय iterators का उपयोग कर संग्रह में ही एक्सेस करने वाले) निर्भरता इंजेक्शन? नियंत्रण का उलटा? न तो?

चलो एक और उदाहरण देखें। हमारे पास एक वर्ग है:

class Dice 
{ 
public: 
    typedef boost::mt19937 Engine; 
    Dice(int num_dice, Engine& rng) : n_(num_dice), eng_(rng) {} 
    int roll() 
    { 
     int sum = 0; 
     for (int i = 0; i < num_dice; ++i) 
      sum += boost::uniform_int<>(1,6)(eng_); 
     return sum; 
    } 
private: 
    Engine& eng_; 
    int n_; 
}; 

यह निर्भरता इंजेक्शन की तरह लगता है। लेकिन क्या यह नियंत्रण में उलटा है?

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

+1

क्या आपने विकी पढ़ी है? आईओसी/डी http://en.wikipedia.org/wiki/Inversion_of_control – CDSO1

+6

सी ++ में, हम आईओसी या डीआई नहीं करते हैं - हमारे पास अपनी खुद की भयानक और बुरी तरह से अवधारणाएं हैं। –

+0

यदि आप सावधान नहीं हैं तो आपका टेम्पलेट फ़ंक्शन विभाजित हो सकता है। –

उत्तर

14

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

उलट और यात्रा

इस मामले "नियंत्रण" में "प्रवाह नियंत्रण" का अर्थ है।

मुझे लगता है कि अपनी पहली यात्रा से जुड़े उदाहरण नहीं वास्तव में नियंत्रण के उलट है, क्योंकि वह कोड स्पष्ट रूप से प्रवाह नियंत्रण करता है। नियंत्रण में उलटा प्रवाह को नियंत्रण से निष्पादित करने के लिए कार्रवाई को अलग करेगा। यह इस तरह लग सकता है (मेरे जावा/सी # क्षमा): प्रत्येक संग्रह तत्व यह दौरा के लिए कुछ

SumVisitor sumVisitor = new SumVisitor(); 
collection.AcceptVisitor(sumVisitor); 
int sum = sumVisitor.GetSum(); 

आगंतुक वस्तु करता है, जैसे कि एक योग काउंटर फ़ील्ड अपडेट करें। लेकिन यह कैसे या पर कोई नियंत्रण है जब यह संग्रह, नियंत्रण की इसलिए उलट द्वारा कहा जाता है। आप MedianVisitor, MeanVisitor, MaximumVisitor, आदि को भी कार्यान्वित कर सकते हैं। प्रत्येक Visit(Element) विधि के साथ एक सामान्य IVisitor इंटरफ़ेस लागू करता है।

संग्रह के लिए, विपरीत सत्य है: संग्रह में प्रत्येक तत्व के लिए visitor.Visit(element) पर कॉल करके विज़िटर क्या करता है और केवल प्रवाह नियंत्रण का ख्याल रखता है इसके बारे में कोई जानकारी नहीं है। विभिन्न विज़िटर कार्यान्वयन सभी संग्रह के लिए समान दिखते हैं। कंट्रोल

उलट और वस्तु ग्राफ निर्माण

इस मामले "नियंत्रण" में "घटक बनाया है और एक साथ वायर्ड रहे हैं कि कैसे पर नियंत्रण" का अर्थ है।

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

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

ऑब्जेक्ट ग्राफ़ निर्माण पर नियंत्रण छोड़ने का एक और तरीका Service Locator पैटर्न है, हालांकि इसमें disadvantages है।

1

मुझे जवाब देने का प्रयास करें।

आपका पहला उदाहरण न तो है। यह बस एक टेम्पलेट है।

यह निर्भरता इंजेक्शन होने के लिए, एक कार्यान्वयन चुना गया है, और टेम्पलेट के लिए प्रदान करना होगा।

आईओसी होने के लिए, टेम्पलेट को कार्यान्वयन प्रकार में रनटाइम (संकलित समय नहीं) पर प्रदान किया जाना चाहिए, और "माध्य()" फ़ंक्शन के कार्यान्वयन के रूप में उपयोग किया जाना चाहिए (एक कारखाने के बारे में सोचें जो मतलब प्रदान करता है समारोह कार्यान्वयन)

आपका दूसरे उदाहरण डि/आईओसी के एक उपभोक्ता की तरह दिखता है। कोड जो आपकी कक्षा में इंजन के कार्यान्वयन को भेजता है वह डीआई/आईओसी घटक होगा।

उम्मीद है कि यह सटीक है, और मदद करता है।

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