जब ऑब्जेक्ट केवल इंटरफ़ेस के भाग का उपयोग करते हैं, तो मैं संरचना को कैसे नियंत्रित करता हूं?


9

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

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

मैंने दूसरों से विरासत में मिलने वाले इंटरफेस (IReadDao, IUpdateDao, IDeleteDao दाओस से विरासत में मिला होगा) होने के बारे में सोचा, लेकिन इस दृष्टिकोण को मूल रूप से कार्यों के प्रत्येक संयोजन के लिए एक अलग इंटरफ़ेस की आवश्यकता होगी (IUpdateAndRead, IReadAndDelete, IReadAndUpdate ... )

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

class IDao {

  void update(ModelDao model);
  void delete(String guid);
  ModelDao read(String guid);

}

Class A {

  private IDao dao;

  public A(IDao dao) {

    this.dao = dao;

  }

  public void doStuff() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void readThenDoSomething(String id) {

    ModelDao model = dao.read(id);

    ...

  }

}

Class B {

  private IDao dao;

  public B(IDao dao) {

    this.dao = dao;

  }

  public void makeUpdate() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void delete(String id) {

    dao.delete(id);

  }

}

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

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

3
मुझे लगता है कि यह इंटरफ़ेस अलगाव सिद्धांत ( Iसे SOLID) का एक आदर्श उदाहरण है । उस पर थोड़ा पढ़ना चाह सकते हैं।
क्रिस्टोफर फ्रांसिस्को

जवाबों:


10

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

दहनशील विस्फोट से बचने के लिए (जैसे IReadUpdate, एक , IDeleteUpdateआदि इंटरफेस की आवश्यकता से बचने के लिए ) आप कंस्ट्रक्टर इंजेक्शन में अलग-अलग इंटरफेस प्रदान कर सकते हैं (आप एक ही वस्तु को दो बार अलग-अलग मापदंडों से पास कर सकते हैं), या दो या दो से अधिक इंटरफेस का समर्थन करने वाली एक ही वस्तु प्रदान करते हैं एक सामान्य विधि कॉल का उपयोग कर extends

कंस्ट्रक्टर इंजेक्शन:

class MyDaoLibrary : IUpdateDao, IInsertDao, IDeleteDao {
    //Etc....
}

class A
{
    //It is OK if the IoC container factory provides the same instance for both parameters.
    a(IUpdateDao dao1, IDeleteDao dao2) {
        this.updater = dao1;
        this.deleter = dao2;
    }
    //Etc....
}

सामान्य विधि का उपयोग करते हुए सेटर इंजेक्शन:

<T extends IUpdateDao & IDeleteDao> void InitializeDao(T dao)  //Pass a single object that implements both IUpdateDao and IDeleteDao

सेटर इंजेक्शन का उपयोग करते समय, मैं उस उदाहरण चर को कैसे घोषित करूंगा जिसे मैं आरोग्यदेवडू फ़ंक्शन में सेट कर रहा हूं?
jteezy14

आपको दो उदाहरण चर (एक को हटाने के लिए, एक अपडेट के लिए) की आवश्यकता होगी ... daoदोनों को असाइन करें।
जॉन वू

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