2012-09-17 19 views
6

जैसा कि मैं एमवीसी के मानक कार्यान्वयन में जानता हूं हमएमवीसी - क्या मुझे दृश्य में नियंत्रक का उपयोग करने की आवश्यकता है?

पर नियंत्रक और मॉडल पास करते हैं लेकिन मैं इस विचार से थोड़ा असहमत हूं। मैं नहीं चाहता कि मेरा विचार दोनों नियंत्रक और मॉडल (ओह संख्या। शायद कभी-कभी मॉडल की ज़रूरतों को देख सके, लेकिन मुझे यकीन है कि वह नियंत्रक के ज्ञान के बिना जी सकता है)

मेरी राय में नियंत्रक को दृश्य और मॉडल का प्रबंधन करना चाहिए, और मॉडल को नियंत्रक और देखने के बारे में जानने की आवश्यकता नहीं है; देखें नियंत्रक को जानने की आवश्यकता नहीं है (मैं मॉडल को बाहर नहीं रखता क्योंकि विचारों के कुछ कार्यान्वयन मॉडल में परिवर्तन सुनने के लिए मॉडल के बारे में जानना आवश्यक है)। तो मेरा विचार यह है कि देखें नियंत्रक के बारे में जानने की आवश्यकता नहीं है।

public class MyView implements ButtonClickListener { 

    private Controller myController; 
    private Button myButton; 

    // I commented out the model because we dont need it now 
    // we are talking about using controller in the view 

    public MyView(Controller c/*, Model m*/) { 
     myController = c; 
     myButton  = new Button(); // lets say that it is "register" button 
     myButton.setOnButtonClickListener(this); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    @Override 
    public void onClick() { 
     myController.tellToModelToDoSomething(); 
    } 

} 

और नियंत्रक::

1. यहाँ एक उदाहरण है

public MyController implements Controller { 

    private Model model; 
    private View view; 

    public MyController(Model model) { 

      this.model = model; 
      this.view = new MyView(this); 

    } 

    public void tellToModelToDoSomething() { 
      model.doSomeActions(); 
    } 


} 

2. और अब मैं कैसे नियंत्रक गुजर बिना इस कार्यान्वयन देख पा रहे हैं:

मेरा दृश्य:

public class MyView { 

    private Button myButton; 

    public MyView() { 
     myButton = new Button(); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    public void setOnRegisterButtonClick(final Command command) { 
     myButton.setOnButtonClickListener(new ButtonClickListener() { 
          @Override 
          public void onClick() { 
           command.execute(); 
          } 
         }); 
    } 

} 

"कमांड" इंटरफेस:

public interface Command { 

    void execute(/*also can handle extra params*/); 

} 

और नियंत्रक:

public MyController implements Controller { 

private Model model; 
private View view; 

public MyController(Model model) { 

     this.model = model; 
     this.view = new MyView(); 

     view.setOnRegisterButtonClick(command); 

} 

public void tellToModelToDoSomething() { 
     model.doSomeActions(); 
} 

private Command command = new Command() { 

    public void execute() { 
      tellToModelToDoSomething(); 
    } 

}; 

}

तो क्यों मुझे लगता है कि दृश्य में नियंत्रक का उपयोग अच्छा नहीं है है:

हम नियंत्रक मिश्रण कर रहे हैं और नई निर्भरताओं को बनाने, कार्यान्वयन देखें।

मुझे लगता है कि दृश्य में केवल उनके साथ दृश्य और संचालन होना चाहिए (और नियंत्रक का उपयोग करना और उसकी कुछ विधियां पहले ही तर्क की तरह दिखती हैं)।

पहले उदाहरण में नियंत्रक को बताता है कि क्या करना है। क्या आप सहमत हैं? ऐसा लगता है कि नियंत्रण नियंत्रक नियंत्रण करता है!

दूसरे उदाहरण नियंत्रक में नियंत्रित करता है कि क्या करना है और सिर्फ देखने के कुछ बटन (केवल दृश्य जानता है क्या बटन यह हो जाएगा) तो क्या करना चाहिए क्लिक किया

मैं हमेशा दूसरी योजना का इस्तेमाल किया करने के लिए कहते हैं, लेकिन पढ़ने के बाद एमवीसी के बारे में एक नई किताब, जो कहती है कि हमें नियंत्रक को देखने के लिए पास करने की जरूरत है, मैं थोड़ा उलझन में हूं।

क्या आप कृपया मुझे समझने में मदद कर सकते हैं कि मैं गलत क्यों हूं और मुझे कुछ उदाहरण दिखाता हूं?

+0

मुझे विश्वास है कि नियंत्रक और देखें सीधे बातचीत नहीं करते हैं। वे मॉडल हालांकि बातचीत करते हैं। इसलिए मॉडल दोनों नियंत्रक और देखें, लेकिन देखें और नियंत्रक एक दूसरे को नहीं जानते हैं। – gigadot

+2

ने कहा है कि। एमवीसी कई रूपों में आता है और वास्तविक प्रत्यारोपण अभ्यास में भिन्न होते हैं। – gigadot

+0

आप सही हैं .., और आप इस उदाहरण में कैसे सोचते हैं, कौन सा कार्यान्वयन बेहतर है? – pleerock

उत्तर

11

कोई एमवीसी मानक नहीं है, क्योंकि कई कार्यान्वयन हैं। यहां कई पाठ्यपुस्तकों में पढ़ाया गया एमवीसी की एक व्याख्या है:

इस व्याख्या में नियंत्रक की परिभाषा यह है कि यह दृश्य से घटनाओं को संभालती है, इसलिए दृश्य को नियंत्रक का उपयोग करना चाहिए।

मानक एमवीसी में, मॉडल में डेटा होता है और डेटा का खुलासा करता है, नियंत्रक मॉडल में हेरफेर करता है और दृश्य से घटनाओं को स्वीकार करता है, और दृश्य मॉडल प्रस्तुत करता है और नियंत्रक के लिए ईवेंट उत्पन्न करता है।

एमवीसी को एक लेनदेन प्रणाली माना जाता है, जहां एक घटना द्वारा एक लेनदेन शुरू किया जाता है। आमतौर पर लेनदेन इस तरह दिखते हैं:

  1. दृश्य पर एक ईवेंट (जैसे बटन क्लिक) उत्पन्न होता है।
  2. घटना की जानकारी नियंत्रक को दृश्य से पास की जाती है।
  3. नियंत्रक इसे बदलने के लिए मॉडल पर विधियों को कॉल करता है (सेटर्स और अन्य मैनिपुलेशन विधियां जो कुछ डेटाबेस अपडेट कर सकती हैं)।

ये पहला चरण वी-सी लिंक और एम-सी लिंक का प्रतिनिधित्व करता है। वी-सी मौजूद है क्योंकि घटनाओं को देखने के बजाय उन्हें सीधे संभालने के बजाय प्रक्रियाओं को संसाधित करने के लिए पारित किया जाता है। एम-सी लिंक मौजूद है क्योंकि मॉडल को निकाले गए ईवेंट के अनुसार नियंत्रक द्वारा अद्यतन किया जाता है।

यहां से, दो पथ हैं। पहला:

  1. लेनदेन समाप्त होता है।
  2. अलग-अलग, यह मॉडल इंगित करने के लिए मॉडल अपनी घटनाओं को चलाता है।
  3. दृश्य मॉडल को सुन रहा है और ईवेंट प्राप्त करता है, और परिवर्तनों को दर्शाने के लिए इसके मॉडल प्रतिनिधित्व को अद्यतन करता है।

यह पहला पथ एम-वी लिंक की एक व्याख्या का प्रतिनिधित्व करता है। एम-वी लिंक 1 है) दृश्य को अपने डेटा के लिए मॉडल से जानकारी प्राप्त करना, और 2) मॉडल को संशोधित करने के बाद से अपडेट करने के लिए कहा गया है।

दूसरा पथ केवल एक चरण है: नियंत्रक ने ईवेंट को संसाधित करने के बाद, दृश्य को अपने सभी UI तत्वों को तुरंत रीफ्रेश करके अपडेट किया है। एम-वी लिंक की यह व्याख्या यह है कि मॉडल बस अपनी जानकारी को दृश्य में प्रदान करता है, जैसा ऊपर दिए गए पहले पथ में एम-वी लिंक से बिंदु # 1 के समान है।

यहाँ अपने कोड MVC वास्तुकला मैं का वर्णन किया है के लिए संशोधित से कुछ:

public class MyView implements View, ModelListener { 

    private Button myButton; 
    private Controller controller; 

    public MyView(Controller controller, Model model) { 
     myButton = new Button(); 
     myButton.setOnButtonClickListener(new ButtonClickListener() { 
      @Override 
      public void onClick() { 
       controller.onRegisterButtonClick(); 
      } 
     }); 
     this.controller = controller; 
     model.addModelListener(this); 
    } 

    public void setRegisterButtonText(String text) { 
     myButton.setText(text); 
    } 

    public void modelUpdated(Model model) { 
     // Update view from model 
    } 
} 

और नियंत्रक:

public MyController implements Controller { 

    private Model model; 
    private View view; 

    public MyController(Model model) { 
     this.model = model; 
     this.view = new MyView(this, model); 
    } 

    private void manipulateModel() { 
     model.doSomeActions(); 
    } 

    public void onRegisterButtonClick() { 
     maniuplateModel(); 
    } 
} 

फिर मॉडल:

public class MyModel implements Model { 
    private List<ModelListener> modelListeners = new ArrayList<ModelListener>(); 

    public void addModelListener(ModelListener ml) { 
     if (!modelListeners.contains(ml)) { 
      modelListeners.add(ml); 
     } 
    } 

    public void removeModelListener(ModelListener ml) { 
     modelListeners.remove(ml); 
    } 

    public void doSomeActions() { 
     // Do something 
     fireUpdate(); 
    } 

    private void fireUpdate() { 
     // Iterates backwards with indices in case listeners want to remove themselves 
     for (int i = modelListeners.size() - 1; i >= 0; i-- { 
      modelListener.modelUpdated(this); 
     } 
    } 
} 

ModelListener है बहुत सरल:

public interface ModelListener { 
    void modelUpdated(Model model); 
} 

यह सिर्फ एक व्याख्या है। यदि आप अलग-अलग हिस्सों के बीच आगे decoupling चाहते हैं, तो आपको Presentation, Abstraction, Control (PAC) pattern में देखना चाहिए। यह एमवीसी की तुलना में अधिक decoupled है, और वितरित सिस्टम के लिए भी महान है। यह सरल वेब, मोबाइल, डेस्कटॉप अनुप्रयोगों के लिए अधिक है, लेकिन कुछ क्लाइंट/सर्वर अनुप्रयोगों और अधिकांश क्लाउड एप्लिकेशन इस दृष्टिकोण से लाभ उठा सकते हैं।

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

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

किसी भी मामले में, एक आर्किटेक्चर का पालन करें, दस्तावेज़ अपने आर्किटेक्चर (इसलिए लोगों को पता है कि आपकी व्याख्या क्या है), और इससे बचें नहीं।

+0

प्रतिक्रिया के लिए धन्यवाद। मैं आपकी सलाह की सराहना करता हूं और पीएसी पैटर्न – pleerock

+0

के बारे में और जानूंगा जो 'माईमोडेल' कक्षा में 'मॉडल लिस्टेनर्स' ऐरेलिस्ट में 'विचार' जोड़ देगा? क्या यह 'MyController' में किया जाएगा जहां' MyController' कक्षा में आप 'मॉडल करेंगे। addModelListener (देखें) '? – CapturedTree

+1

निश्चित रूप से, मुझे लगता है कि नियंत्रक इस उदाहरण में उचित जगह होगी। तो नियंत्रक कन्स्ट्रक्टर में: 'model.addModelListener (देखें);' वैकल्पिक रूप से, आपके पास 'व्यू' इंटरफ़ेस 'मॉडल लिस्टनर' का विस्तार हो सकता है ताकि आप जान सकें कि यह हमेशा श्रोता होगा। या 'व्यू' इंटरफेस एक विधि को कार्यान्वित करता है जो 'मॉडल लिस्टर' लौटाता है। बहुत सारे विकल्प हैं। जैसे मैंने कहा, एक कार्यान्वयन चुनें और इसके साथ चिपके रहें :) – Brian