मॉडल और दृश्य के साथ काम करते समय बनाम बहुरूपता पर स्विच करें


12

मैं अपनी समस्या का बेहतर समाधान नहीं निकाल सकता। मेरे पास एक दृश्य नियंत्रक है जो तत्वों की एक सूची प्रस्तुत करता है। वे तत्व ऐसे मॉडल हैं जो B, C, D, आदि का उदाहरण हो सकते हैं और A. से इनहेरिट कर सकते हैं। इसलिए उस व्यू कंट्रोलर में, प्रत्येक आइटम को एप्लिकेशन की एक अलग स्क्रीन पर जाना चाहिए और उपयोगकर्ता द्वारा उनमें से किसी एक को चुनने पर कुछ डेटा पास करना चाहिए। । मेरे दिमाग में आने वाले दो विकल्प हैं (कृपया सिंटैक्स को अनदेखा करें, यह कोई विशिष्ट भाषा नहीं है)

1) स्विच (मुझे पता है कि बेकार है)

//inside the view controller
void onClickItem(int index) {
    A a = items.get(index);

    switch(a.type) {
         case b:
             B b = (B)a;
             go to screen X;
             x.v1 = b.v1; // fill X with b data
             x.v2 = b.v2; 
         case c:
             go to screen Y;
         etc...
    }
}

2) बहुरूपता

//inside the view controller
void onClickItem(int index) {
    A a = items.get(index);
    Screen s = new (a.getDestinationScreen()); //ignore the syntax
    s.v1 = a.v1;   // fill s with information about A
    s.v2 = a.v2;
    show(s);
}

//inside B
Class getDestinationScreen(void) {
    return Class(X);
}

//inside C
Class getDestinationScreen(void) {
    return Class(Y);
}

समाधान 2 के साथ मेरी समस्या यह है कि चूंकि बी, सी, डी, आदि मॉडल हैं, इसलिए उन्हें संबंधित सामग्री को देखने के बारे में पता नहीं होना चाहिए। या वे उस मामले में होना चाहिए?

जवाबों:


6

मुझे लगता है कि शायद आगंतुक पैटर्न का कार्यान्वयन यहां उपयोगी होगा। बी, सी और डी वर्ग को देखने के प्रकार को निर्धारित करने के लिए "दौरा" करना होगा, लेकिन विचारों के बारे में कुछ भी जानने की आवश्यकता नहीं होगी। ViewFactory (नीचे) आइटम का दौरा करेगा और निर्माण के लिए सही दृश्य निर्धारित करने के लिए बहुरूपता का उपयोग करेगा। कोई स्विच स्टेटमेंट नहीं। मॉडल इंटर्नल के बारे में नहीं पूछें कि क्या बनाना है। विज़िटर इंटरफ़ेस दृश्य के लिए सही सेटर का चयन करने के लिए बहुरूपता का उपयोग करता है। सेटर आइटम को विशिष्ट दृश्य प्रकार (X या Y या Z) के निर्माता को पास कर सकता है और फिर वह दृश्य आइटम से उसके फ़ील्ड्स को पॉप्युलेट कर सकता है।

   //inside the view controller
   void onClickItem(int index) {
      ViewFactoryVisitable a = items.get(index);
      ViewFactory aViewFactory = new ViewFactory(
      s = aViewFactory.getViewFor(a);
      show(s);
   }

--------

//Element interface
public interface ViewFactoryVisitable
{
    public void accept(ViewFactory theViewFactory);
}

---------

public interface ViewFactoryVisitor
{
   // one for each concrete type, polymorphism will choose correct setter
   public set setViewFor(B b);
   public set setViewFor(C c);
   public set setViewFor(D d);
}

--------

// B, C, D must implement this visitable interface
class B implements ViewFactoryVisitable
{ 
   ...

   //accept the ViewFactory as a visitor
   public void accept(ViewFactoryVisitor theViewFactoryVisitor)
   {
      theViewFactoryVisitor. setViewFor(this);
   }

   ...
} 

--------

class ViewFactory implements ViewFactoryVisitor
{
   ViewFactory(ViewFactoryVisitable theItem) {
      theItem.accept(this);
   }

   private View mView = null;
   ...

   public void setViewFor(B b) {
      // construct a view x and populate with data from b
      mView = new ViewX(b); 
   }

   public void setViewFor(C c) {
      mView = new ViewY(c); 
   }

   public void setViewFor(D d) {
      mView = new ViewZ(d); 
   }

   View getView() {
      return mView;
   }

} 

1
के कार्यान्वयन को स्वीकार नहीं किया जाना चाहिए "TheViewFactoryVisitor.setViewFor (यह);" क्षमा करें यदि मैं बेवकूफ हूँ!
रयान

@ रियान गुड कैच। यह गलती यहाँ 3 साल से है!
बजे चक क्रट्सिंगर

1

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

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

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

मुझे लगता है कि यह ऑब्जेक्ट ओरिएंटेड डिज़ाइन की एक बहुत ही सामान्य और मौलिक समस्या है।


0

मुझे लगता है कि स्विच के साथ जाना इस मामले के लिए बहुरूपता के साथ जाने से बेहतर विकल्प है।

यह करने के लिए एक काफी सरल बात है, इसलिए मुझे नहीं लगता कि इसे बहुरूपता के उपयोग से अधूरा होना है।

मैं इस ब्लॉग पोस्ट में सिक्का देना चाहूंगा । स्विच स्टेटमेंट आवश्यक रूप से बदसूरत नहीं हैं जब तक आप उन्हें ठीक से उपयोग नहीं करते हैं। और आपके मामले में, नियंत्रक में उपयोग के लिए उस तरह के मॉडल को ओवरकिल किया जा सकता है और अवांछित परिणाम सामने ला सकता है। जैसे SRP का उल्लंघन करना।


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

1
कोई चिंता नहीं, बस बात पर मेरे 2 सेंट दे। हालाँकि, अपने मॉडल में दृश्य तर्क रखने के साथ आपकी समस्या को हल करने के लिए, आप हमेशा उन्हें केवल डेकोरेटर्स के साथ लपेट सकते हैं ताकि आपके मॉडल दृश्य तर्क से मुक्त रहें। फिर आप मॉडल के बजाय डेकोरेटर कक्षाओं पर बहुरूपता का उपयोग कर सकते हैं।
मारू

0

समाधान 2 के साथ मेरी समस्या यह है कि चूंकि बी, सी, डी, आदि मॉडल हैं, इसलिए उन्हें संबंधित सामग्री को देखने के बारे में पता नहीं होना चाहिए।

मैं इस चिंता से सहमत हूं। मैं भी थोड़ा चिंतित हूं कि कॉम्बोक्स में बैठने वाली वस्तुओं का व्यवहार होगा। मुझे यकीन नहीं है कि यह एक "बुरी चीज" है जो कभी नहीं किया है, यह सिर्फ मेरे लिए एक अप्राकृतिक पसंद की तरह लगता है।

इसके अलावा, ऐसा नहीं लगता है Aऔर यह उपवर्गों के प्रकार हैं जिनके साथ आपके पास दिलचस्प बहुरूपता है। दिलचस्प प्रकार वास्तव में है Screen। इस उदाहरण में, Aसिर्फ एक वर्ग है जो Screenसृजन को सूचित करने के लिए जानकारी रखता है ।

यदि आप कॉम्बोक्स बनाते हैं a.typeतो जो भी रिटर्न की सूची होती है, तो एक स्विच स्टेटमेंट अधिक स्वाभाविक लगता है। हालांकि, मैं इसे क्लिक इवेंट हैंडलर में डालने के बजाय इसे एक में डालूंगा ScreenFactory। फिर आपके पास है:

//inside the view controller
void onClickItem(int index) {
    A a = items.get(index);

    s = _screenFactory.GetScreen(a);
    show(s);
    }
}

//inside a ScreenFactory implementation
internal Screen GetScreen(A typeIndicator)
{
switch(a.type) {
     case b:
         return new ScreenX();
     case c:
         return new ScreenY();
     etc...        
}

यह आपको स्क्रीन बिल्डिंग व्यवहार का परीक्षण करने देता है, और आपके UI से कुछ कार्यक्षमता खींचता है। यह आपके व्यू को लेयरिंग को बरकरार रखता है। शायद यह आपके डिज़ाइन को सरल करता है, अगर इसका मतलब है Aऔर उपवर्गों को उस typeझंडे में ढहाया जा सकता है जिसमें वे शामिल हैं।


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