2010-02-24 17 views
8

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

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

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

+0

आप बहुत सही हैं !!! – Faruz

+0

शायद आप अपनी शिकायतों/संदेहों को एक प्रश्न में तैयार कर सकते हैं? –

+0

सवाल यह होगा कि मुझे एमवीवीएम के बारे में कुछ याद आ रहा है या क्या कोई बेहतर तरीका है? –

उत्तर

3

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

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

सूची बॉक्स के लिए, मैं ViewModem प्रॉपर्टी को व्यूमोडेल पर किसी संपत्ति पर जोड़ता हूं। INotifyPropertyChanged के साथ, आपके कोड का कोई भी हिस्सा परिवर्तन पर प्रतिक्रिया कर सकता है।

व्यूमोडल्स के बीच संचार एक अच्छा सवाल है। यदि आपको एक ही स्क्रीन पर अलग-अलग विचारों की आवश्यकता है, तो आपके पास "सुपर" दृश्य मॉडल हो सकता है जिसमें प्रत्येक दृश्य का दृश्य मॉडल शामिल हो। वहां कुछ एमवीवीएम फ्रेमवर्क हैं। मैंने Mark Smith's MVVM helpers के कुछ हिस्सों का उपयोग किया, जो काफी हल्का और उपयोगी है।

3

खैर एक नया आदेश है कि ICommand impelements लिख लगता मारने वाली चीजों पर कुछ इस वर्ग पर एक नजर है: VB.NET: सार्वजनिक कक्षा RelayCommand इम्प्लीमेन्ट्स ICommand

#Region " Declarations" 
    Private mCanExecute As Predicate(Of Object) 
    Private mExecute As Action(Of Object) 
#End Region 

#Region " Constructors" 
    Public Sub New(ByVal canExecute As Predicate(Of Object), ByVal execute As Action(Of Object)) 
     mCanExecute = canExecute 
     mExecute = execute 
    End Sub 

    Public Sub New(ByVal execute As Action(Of Object)) 
     mCanExecute = Nothing 
     mExecute = execute 
    End Sub 
#End Region 

#Region " Events" 
    Public Custom Event CanExecuteChanged As EventHandler Implements System.Windows.Input.ICommand.CanExecuteChanged 
     AddHandler(ByVal value As EventHandler) 
      AddHandler CommandManager.RequerySuggested, value 
     End AddHandler 
     RemoveHandler(ByVal value As EventHandler) 
      RemoveHandler CommandManager.RequerySuggested, value 
     End RemoveHandler 
     RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs) 
      Throw New ApplicationException("Can't raise custom command!") 
     End RaiseEvent 
    End Event 
#End Region 

#Region " Public Methods" 
    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute 
     If (mCanExecute Is Nothing) Then 
      Return True 
     End If 
     Return mCanExecute(parameter) 
    End Function 

    Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute 
     mExecute(parameter) 
    End Sub 
#End Region 

End Class 

सी #

public class RelayCommand : ICommand 
{ 

    #region Declarations 
    private Predicate<object> mCanExecute; 
    private Action<object> mExecute; 
    #endregion 

    #region Constructors 
    public RelayCommand(Predicate<object> canExecute, Action<object> execute) 
    { 
     mCanExecute = canExecute; 
     mExecute = execute; 
    } 

    public RelayCommand(Action<object> execute) 
    { 
     mCanExecute = null; 
     mExecute = execute; 
    } 
    #endregion 

    #region Events 
    public event EventHandler CanExecuteChanged { 
     add { 
      CommandManager.RequerySuggested += value; 
     } 
     remove { 
      CommandManager.RequerySuggested -= value; 
     } 
    } 
    #endregion 

    #region Public Methods 
    public bool CanExecute(object parameter) 
    { 
     if ((mCanExecute == null)) { 
      return true; 
     } 
     return mCanExecute(parameter); 
    } 

    public void Execute(object parameter) 
    { 
     mExecute(parameter); 
    } 
    #endregion 

} 

और इसका उपयोग करने के लिए बस आईसीओएमएंड की एक संपत्ति का पर्दाफाश करें जो एक नए रिले कॉमांड को एक समारोह में प्रतिनिधियों के साथ देता है ...

vb.net

Private mDeleteCommand As ICommand 

Public ReadOnly Property DeleteCommand() As ICommand 
    Get 
     If (mDeleteCommand Is Nothing) Then 
      mDeleteCommand = New RelayCommand(AddressOf CanDeleteTodo, AddressOf DeleteTodo) 
     End If 
     Return mDeleteCommand 
    End Get 
End Property 

सी #

private ICommand mDeleteCommand; 
public ICommand DeleteCommand { 
    get { 
     if ((mDeleteCommand == null)) { 
      mDeleteCommand = new RelayCommand(CanDeleteTodo, DeleteTodo); 
     } 
     return mDeleteCommand; 
    } 
} 
+0

बहुत बहुत धन्यवाद, मैंने जोश स्मिथ द्वारा उत्कृष्ट लेख पर यह कोड देखा, और वास्तव में सहायक है, लेकिन यह अभी भी प्रश्नों को खुला छोड़ देता है कि हमें हमेशा आदेशों का उपयोग करने की आवश्यकता क्यों है? क्या कोड में घटनाएं स्वाभाविक रूप से बुराई के पीछे हैं या क्या कुछ परिस्थितियां हैं जब वे उचित हैं? –

+0

एक विशेषज्ञ से बहुत दूर है, लेकिन अगर मैं कर सकता हूं तो मैं अपना व्यू कोड खाली छोड़ने की कोशिश करता हूं, इसलिए जहां तक ​​मुझे पता है कि आप किसी ईवेंट में डेटाबेस नहीं कर सकते हैं ताकि आपको कमांड के साथ छोड़ दिया जा सके .. (और मुझे यह कहना होगा कि एक शुद्ध एक्सएएमएल दृश्य अच्छा है आपको बस एक ही स्थान पर देखना है) – Peter

+0

पीछे कोड ViewModel नहीं है। ViewModel में कोड निष्पादित करने के लिए दृश्य प्राप्त करने का सबसे आसान तरीका गुई ऑब्जेक्ट को कमांड को बाध्य करना है। कोड के पीछे कोड हैंडलर व्यूमोडेल को कॉल कर सकते हैं, लेकिन यदि आप बाइंडिंग का उपयोग करते हैं तो आप बिचौलियों को काटते हैं। –

0

ठीक है ताकि भविष्य में संदर्भ के लिए इस धागे को कुछ प्रकार का बंद कर दिया जा सके। सबसे पहले जवाब के लिए बहुत बहुत धन्यवाद। रिलेकॉमैंड वास्तव में एक अच्छा विचार है; यह वास्तव में चीजों को व्यवस्थित करता है और परीक्षण और काम करने में आसान बनाता है। ऐसा लगता है कि यह जाने का रास्ता है। SelectedItem को बाध्यकारी आइटम नियंत्रण में कमांड समर्थन की कमी के संबंध में समस्या को हल करने लगता है। ViewModels के बीच संचार के संबंध में, मुझे विश्वास नहीं है कि एक सुपर व्यू मॉडल होने से मेरी समस्या हल हो जाती है, क्योंकि यह मेरे दृश्य पेड़ के लिए मॉडल से जुड़ा हुआ है। इसके अलावा मुझे इस ढांचे में अलग-अलग पदानुक्रमों में सभी दृश्य मॉडल के बीच संवाद करने के लिए एक स्वच्छ, वस्तु स्वतंत्र तरीका रखने का कोई तरीका नहीं मिला है। तो मैं जो कोशिश कर रहा हूं वह पहले एक केंद्रीकृत मॉडल बना रहा है जो एक सिंगलटन है जो INotifyPropertyChanged इंटरफ़ेस लागू करता है। व्यूमोडेल के पास इस मॉडल का एक उदाहरण हो सकता है और हमारे अच्छे पुराने दोस्त ऑब्जर्वर पैटर्न का उपयोग करके संबंधित संपत्ति परिवर्तनों का प्रचार करने पर कार्य कर सकता है। ठीक काम करने के लिए लगता है, हालांकि मैं परिपत्र संदर्भों से थोड़ा चिंतित हूं। तुम क्या सोचते हो?

1

मेरा अनुरोध स्वीकार जूलियो,

देखो इस तरह एक पुरानी पोस्ट है, लेकिन मैं वास्तव में अपने प्रश्न से प्यार है।

हाल ही में मैं एक फ्लेक्स प्रोग्रामर और एक डब्ल्यूपीएफ भी हूं। मुझे केर्न्गॉर्म पता था (कहें [सी]) फ्रेमवर्क अच्छी तरह से, पार्सले फ्रेमवर्क का उपयोग करके Presentation model का उपयोग करना सीखा है, और डब्ल्यूपीएफ में मुझे एहसास हुआ है कि प्रेजेंटेशन मॉडल को एमवीवीएम पैटर्न में बदल दिया गया है।

कमान

कमान में [C] MVVM की तुलना में अलग है, में [C] एक Command Pattern, के रूप में अधिक संतुष्ट है कमान जहां [C] Invoker के रूप में नियंत्रक अधिनियम, में में ऐसा [C] वास्तव में चेन, पूर्ववत, लेनदेन इत्यादि का समर्थन करने के लिए कमांड बनाया जा सकता है। एमवीवीएम कमांड में कमांड पैटर्न से बहुत दूर है। एमवीवीएम में कमांड का उपयोग करने का मुख्य विचार क्योंकि आईसीओएमएंड ऑपरेशन के साथ बाध्यकारी करने का एकमात्र तरीका है। फ्लेक्स में आप click="{viewmodel.doOperation()}" का उपयोग करके ईवेंट को आसानी से बाध्य करते हैं लेकिन WPF में नहीं।

मॉडल लोकेटर

यह एक बुरा व्यवहार की तरह [C] किया एक भी मॉडल लोकेटर पर अपने आवेदन राज्य केंद्रीकृत करने के लिए है। दूसरी तरफ, यदि आप ऐसा करते हैं तो आप अपने कोड का परीक्षण "आसानी से" इकाई का मौका खो देंगे। आपके कोड पर जितना अधिक निर्भर होगा उतना ही आपका परीक्षण जितना कठिन होगा, अगर आपके मॉडल लोकेटर में आपके छोटे कोड पर निर्भरता है, तो आप पहले से ही अपने कोड पर निर्भरता की बड़ी मात्रा डाल सकते हैं। और, सिंगलटन का उपयोग करने वाली सबसे डरावनी चीज़ यह है कि नकली करना असंभव है। इसलिए यदि आपका मॉडल लोकेटर आपकी यूनिट परीक्षण प्रक्रिया से गैर यूनिट-परीक्षण अनुकूल है तो दर्द से भरा हो सकता है।

वास्तव में आपके विचारों के बीच साझा मॉडल के लिए एमवीवीएम के संदर्भ में उपयोग नहीं किया गया है, लेकिन आपको इसे प्राप्त करने के लिए dependency injection शब्द देखना चाहिए।

बेस्ट सादर

+0

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

+0

हाँ मैं सहमत हूं, कुछ मामलों में यह स्वीकार्य है, लेकिन कार्यक्रमों के लिए अच्छी गुणवत्ता वाले सॉफ्टवेयर के लिए हमें कुछ बेहतरीन अभ्यासों का पालन करना चाहिए, आप इसे यहां देख सकते हैं http://misko.hevery.com/2008/08/17/singletons-are -pathological-झूठे /। लिंक जो मैं सिंगलटन के बारे में चर्चा करता हूं लेकिन वास्तव में ग्लोबल स्टेट के बारे में उल्लेख करता हूं जो प्रोग्रामिंग पर सबसे अच्छा अभ्यास नहीं था। मार्क करें कि मैं जो लिंक प्रदान करता हूं वह लेखक Google डेवलपर का ** एग्इल कोच ** है। – ktutnik

0

MVVM के बारे में चर्चा के लोग यह भी सैद्धांतिक दिखाई दिया है और फ्लेक्स कि फ्लेक्स से आने वाले लोगों के लिए MVVM थोड़ा जटिल बना देता है सभी को एक साथ वास्तव में अलग वास्तुकला है।

मैं आपको बहुत ही सरल उदाहरण देता हूँ,

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

तो मूल रूप से आप एक एमएक्सएमएल फ़ाइल में मॉडल + व्यू + कंट्रोलर को आसानी से व्यवस्थित कर सकते हैं।

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

चीजों को आसान बनाने के लिए, एमवीवीएम आपको विभिन्न फाइलों को परिभाषित करने के लिए मजबूर करता है।

आप एक फ़ाइल है, कि है कि आपके ViewModel, जो मूल रूप से मॉडल + कमांड का संयोजन है है खुद अपने मॉडल, उदाहरण के Customer.cs

आप किसी अन्य फाइल के लिए है। और आप कमांड के निष्पादित कार्यक्रम में अपना कंट्रोलर कोड लिखते हैं।

आपके पास एक और फ़ाइल है, जो आपका दृश्य है, मूल रूप से व्यूमोडेल के सभी गुणों से जुड़ा हुआ है जो मॉडल या कमांड हैं।

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