小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

.NET程序員應該熟悉的開發(fā)模式

 orion360doc 2011-03-12

 

http://www./html/51/n-226051.html

我們總會有這樣一個經(jīng)驗:一個系統(tǒng)最不容易也最不應該變化的部分是領域邏輯,最容易變化也最應該變化的是數(shù)據(jù)的呈現(xiàn)方式。

  在Java的各種應用中可以說是到處可見MVC,J2EE貫穿MVC的概念,android的開發(fā)方式也是類MVC的,MVC結(jié)構對于做過Java應用的人而言簡直就是司空見慣。而在.NET這邊,由于之前微軟為大家提供的各種winform、ASP.NET項目典范(比如那個petshop series)將“三層”概念很好的灌輸?shù)搅?NET程序員的大腦中,許多.NET開發(fā)者凡是做個東西都要搬出自己最拿手的IModel、IDAL這樣的神器。

  其實MVC與所謂的“三層架構”是兩個層次上的東西,前者是一種結(jié)構模式,而后者則是分層的角度去說。

  一件很奇怪的事情,許多人知道“三層”卻不知道MVC,其實這要歸結(jié)與.NET的早期開發(fā)技術ASP.NET和winform這些page controller的典范讓許多人對三層夸夸其談卻對MVC視而不見甚至一無所知。什么是page controller模式呢?搞.NET的大多都用過winform和webform,這種xxxform用起來很直觀,我們想要做一個程序,ok,最簡單的方式就是拖拖拽拽幾個控件,然后在一個叫code behind的東西里寫這些UI事件的處理邏輯,加一大堆變量用于記錄數(shù)據(jù)和狀態(tài),這樣一個程序就能出爐。這種開發(fā)方式對于一些小軟件系統(tǒng)的開發(fā)其實效率還是蠻高的,后來人們看到其弊端---一旦修改UI,事件處理就要跟著變,但是業(yè)務還是那個業(yè)務,憑什么要修改非UI的代碼?于是有人提出“三層”,最樸素的理解就是將原本那堆事件處理里的code分成業(yè)務代碼和數(shù)據(jù)庫訪問代碼并轉(zhuǎn)移到其它類中,做多了就把那坨UI叫做UI,那坨業(yè)務代碼叫做BLL,那坨DAO叫做DAL。也就是這種架構:

  而對于J2EE的開發(fā)者來說熟悉的是下圖。

  說明:這兩幅圖copy自是daxnet文

  MVC是什么

  MVC是一個很經(jīng)典的結(jié)構,并且其又其思想衍生出很多變種比如MVP,MVVP。傳統(tǒng)的MVC結(jié)構之一是這樣的(拿主動型MVC來說):

  比如web開發(fā)(比如ASP.NET MVC或者是Java的web開發(fā)方式),view就是純web頁面或者webservice,當提交一個表單/調(diào)用webservice或者ajax后會將數(shù)據(jù)提交給controller(當然期間可能會經(jīng)過各種filterchain、listener這樣的東西)controller調(diào)用相應的業(yè)務模塊來處理這個請求,最終結(jié)果會更新View的顯示。

  MVP

  對于非天然MVC的框架

  對于ASP.NET/winform而言,雖然可以通過改造讓其支持MVC結(jié)構的開發(fā)(比如通過定制IHttpModule、IHttpHandler云云),但是在企業(yè)看來這些都算是邪門武功(因為這樣會喪失xxxform在開發(fā)上的很多特性比如快速開發(fā))。大多數(shù)使用的是mvp模式。什么是mvp呢?其實mvp是MVC的一個變種。因為用winform或者webform的話form始終是個阻礙MVC開發(fā)的問題。那么好,我們?nèi)匀皇褂胐esigner和codebehind,其實一個架構設計的好壞是取決于人而不是具體的技術的,只要我們OO一時強page controller一樣好用。



/////////////////////////////////////////////////////////////

  在MVP模式中我們需要自己定制各個View(web頁面或者窗體)對應的IView和IPresenter、IModel。IView要對IPresenter暴露操作UI、數(shù)據(jù)綁定的接口,IPresenter對IView要暴露當UI事件觸發(fā)需要調(diào)用的接口,IPresenter根據(jù)IView傳遞過來的請求調(diào)用業(yè)務接口并根據(jù)結(jié)果操作UI。舉個簡單的例子,一個計算“x+y=?”的程序。如果我們這樣定義IPresenter和IView

  1. public interface IPresenter   
  2.     {   
  3.         IView View { getset; }   
  4.         void CalculateResult();   
  5.     }  
  6.  
  7. public interface IView   
  8.     {   
  9.         IPresenter Presenter { getset; }   
  10.         void ShowResult(string result);   
  11.         int ValueOne { get; }   
  12.         int ValueTwo { get; }   
  13.     } 

  IPresenter的實現(xiàn)如下(這里從簡把IModel去掉了)

  Presenter

  1. namespace ClientLibrary  
  2. {  
  3.     public class Presenter : IPresenter  
  4.     {  
  5.         private IView _view;  
  6.         public IView View  
  7.         {  
  8.             get 
  9.             {  
  10.                 return _view;  
  11.             }  
  12.             set 
  13.             {  
  14.                 _view = value;  
  15.                 _view.Presenter = this;  
  16.             }  
  17.         }  
  18.  
  19.         private static readonly string RESULT_FORMATTER = "{0}+{1},the result is {2}";  
  20.         public void CalculateResult()  
  21.         {  
  22.             if (_view != null)  
  23.             {  
  24. var result = string.Format(RESULT_FORMATTER, _view.ValueOne, _view.ValueTwo, _view.ValueOne + _view.ValueTwo);  
  25.                 _view.ShowResult(result);  
  26.                 this.A = 123;  
  27.             }  
  28.         }  
  29.         private int _a;  
  30.         public int A  
  31.         {  
  32.             set 
  33.             {  
  34.                 A = value;  
  35.             }  
  36.         }  
  37.     }  

/////////////////////////////////////////////////////////////

 

View的實現(xiàn)如下(那silverlight為例,換成別的也行)

  MainPage

  1. namespace debug  
  2. {  
  3.     public partial class MainPage : UserControl, IView  
  4.     {  
  5.         public MainPage()  
  6.         {  
  7.             InitializeComponent();  
  8.         }  
  9.  
  10.         private IPresenter _presenter;  
  11.  
  12. private void btn_Click(object sender, RoutedEventArgs e)  
  13.         {  
  14.             if (_presenter != null)  
  15.             {  
  16.                 _presenter.CalculateResult();  
  17.             }  
  18.             #region hidden  
  19.             /*int total = 0;  
  20.             try  
  21.             {  
  22. total = int.Parse(tb1.Text) + int.Parse(tb2.Text);  
  23. MessageBox.Show("計算結(jié)果:" + total.ToString());  
  24.             }  
  25.             catch (Exception ex)  
  26.             {  
  27.                 MessageBox.Show("出錯啦" + ex.ToString());  
  28.             }  
  29.             finally  
  30.             {  
  31.                 tb1.Text = string.Empty;  
  32.                 tb2.Text = string.Empty;  
  33.             }*/ 
  34.             #endregion  
  35.  
  36.         }  
  37.  
  38.         public IPresenter Presenter  
  39.         {  
  40.             get 
  41.             {  
  42.                 return _presenter;  
  43.             }  
  44.             set 
  45.             {  
  46.                 _presenter = value;  
  47.             }  
  48.         }  
  49.  
  50.         public void ShowResult(string result)  
  51.         {  
  52.             MessageBox.Show(result);  
  53.         }  
  54.  
  55.         public int ValueOne  
  56.         {  
  57.             get { return int.Parse(tb1.Text); }  
  58.         }  
  59.  
  60.         public int ValueTwo  
  61.         {  
  62.             get { return int.Parse(tb2.Text); }  
  63.         }  
  64.     }  

  一個很簡單的東西,看上去寫成的要多些那么一坨東西,但是好處是顯而易見的,就是更換view非常方便,根本不用去改你的IPresenter、Presenter和業(yè)務。一切都是接口調(diào)用而不依賴具體實現(xiàn),這就是好處。


/////////////////////////////////////////////////////////////

 

你必須要懂的MVVM

  對于.NET平臺的開發(fā)人員,托微軟的福分我們擁有一種更為強大的模型---MVVM。這應該算是做WPF/Silverlight應用的人必懂的一種結(jié)構,WPF/silverlight天生支持數(shù)據(jù)綁定和命令綁定(不過sl在命令綁定上還比較弱),這就為我們使用MVVM創(chuàng)造了可能。

  View是什么呢,純的View只有xaml或者附帶必要的只與View本身相關邏輯代碼。ViewModel,你可以把它理解為View具體呈現(xiàn)內(nèi)容所依賴數(shù)據(jù)的一個抽象,在MVVM中View與ViewModel總會有一種綁定關系,一旦ViewModel中被綁定的數(shù)據(jù)發(fā)生改變View上的數(shù)據(jù)就會跟著變,相反也有可能,比如你的賬號密碼框內(nèi)容發(fā)生變化,關聯(lián)的ViewModel中的數(shù)據(jù)就會被框架自動通知到。

  在wpf/silverlight中,綁定是通過xaml語法來完成(雖然你可以選擇用c#來寫但不符合mvvm的宗旨),并且綁定雙方的通知機制是有框架來完成,也就是說一個會xaml和blend的美工只需事先和coder商量下“咱們的xx和xx是在哪個ViewModel上叫XXX的屬性的XXX屬性……”問題之后就可以各干各的了。那么ViewModel怎么寫,咋view中又怎么綁定到viewmodel呢?首先我們談ViewModel。

  說道ViewModel你需要知道依賴屬性和依賴對象的概念,這是wpf/silverlight的基礎所以不多說。有兩種方式寫ViewModel。第一種是自己去實現(xiàn)INotifyPropertyChanged接口,并在屬性變化時去調(diào)用NotifyPropertyChanged事件。

  為了方便我們定義一個ViewModelBase的抽象基類,然后讓其他ViewModel繼承這個基類。

  ViewModelBase

  1. public abstract class ViewModelBase : System.ComponentModel.INotifyPropertyChanged, IDisposable   
  2.     {   
  3.         public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;   
  4.         protected void OnPropertyChanged(string propertyName)   
  5.         {   
  6.             if (PropertyChanged != null)   
  7.             {   
  8.       var arg = new System.ComponentModel.PropertyChangedEventArgs(propertyName);   
  9.                 PropertyChanged(this, arg);   
  10.             }   
  11.         }   
  12.         public virtual void Dispose()   
  13.         {   
  14.              
  15.         }   
  16.     } 

  1. DemoViewModel public class DemoViewModel : ViewModelBase     
  2.  {          
  3. #region fields          
  4. private string _propertyA;          
  5. #endregion          
  6. #region presentation properties          
  7. public string PropertyA          
  8. {              
  9. get              
  10. {                 
  11.  return _propertyA;           
  12.    }              
  13. set        
  14.       {                  
  15. if (_propertyA != value)                
  16. {                      
  17. _propertyA = value;                   
  18. base.OnPropertyChanged("PropertyA");             
  19.      }         
  20.      }        }        
  21.   #endregion    } 

/////////////////////////////////////////////////////////////

 第二種是利用DependencyObject和DependencyProperty。

  PeopleItemViewModel

  • public class PeopleItemViewModel : DependencyObject, IPeopleItemViewModel  
  •     {  
  •         public PeopleItemViewModel()  
  •         {  
  •               
  •         }  
  • public static readonly DependencyProperty SimpleUserDataProperty = DependencyProperty.Register("SimpleUserData"typeof(SimpleUserData), typeof(PeopleItemViewModel));  
  • public static readonly DependencyProperty RelativeSimpleUserDataProperty = DependencyProperty.Register("RelativeSimpleUserData"typeof(ObservableCollection<SimpleUserData>), typeof(PeopleItemViewModel));  
  • public static readonly DependencyProperty AllSimpleUserDataProperty = DependencyProperty.Register("AllSimpleUserData"typeof(ObservableCollection<SimpleUserData>), typeof(PeopleItemViewModel));  
  •  
  •         public SimpleUserData SimpleUserData  
  •         {  
  •             get 
  •             {  
  •                 return (SimpleUserData)base.GetValue(SimpleUserDataProperty);  
  •             }  
  •             set 
  •             {  
  •                 if (!base.CheckAccess())  
  •                 {  
  •                     Dispatcher.Invoke(new Action(  
  •                         () =>  
  •                         {  
  •                             SimpleUserData = value;  
  •                         }));  
  •                 }  
  •                 else 
  •                     base.SetValue(SimpleUserDataProperty, value);  
  •             }  
  •         }  
  •         public ObservableCollection<SimpleUserData> RelativeSimpleUserData  
  •         {  
  •             get 
  •             {  
  • return (ObservableCollection<SimpleUserData>)base.GetValue(RelativeSimpleUserDataProperty);  
  •             }  
  •             set 
  •             {  
  •                 if (!base.CheckAccess())  
  •                 {  
  •                     Dispatcher.Invoke(new Action(  
  •                         () =>  
  •                         {  
  •                             RelativeSimpleUserData = value;  
  •                         }));  
  •                 }  
  •                 else 
  •                 {  
  • base.SetValue(RelativeSimpleUserDataProperty, value);  
  • var collectionView = CollectionViewSource.GetDefaultView(value);  
  • collectionView.SortDescriptions.Add(new SortDescription("Distance", ListSortDirection.Ascending));  
  •                 }  
  •             }  
  •         } 
  •  

    //////////////////////////////////////////////////////////////////

  •   public ObservableCollection<SimpleUserData> AllSimpleUserData  
  •         {  
  •             get 
  •             {  
  •       return (ObservableCollection<SimpleUserData>)base.GetValue(AllSimpleUserDataProperty);  
  •             }  
  •             set 
  •             {  
  •                 if (!base.CheckAccess())  
  •                 {  
  •                     Dispatcher.Invoke(new Action(  
  •                         () =>  
  •                         {  
  •                             AllSimpleUserData = value;  
  •                         }));  
  •                 }  
  •                 else 
  •                 {  
  • base.SetValue(AllSimpleUserDataProperty, value);  
  • var collectionView = CollectionViewSource.GetDefaultView(value);  
  • collectionView.SortDescriptions.Add(new SortDescription("Distance", ListSortDirection.Ascending));  
  •                 }  
  •             }  
  •         }  
  •   在View中綁定ViewModel。

      為了方便,我們可以在app.xaml中將需要的viewmode放到全局資源字典中。

      然后再我們的vs視圖設計器Properties(中文版顯示的是“屬性”)頁上選擇為綁定源設置綁定目標(包括source和path等)以及必要的值轉(zhuǎn)換器等等即可。

     ?。≒S:雖然vs很強大,但個人還是建議熟悉xaml的綁定語法,想當初用vs2008搞wpf的時候貌似還沒有這么方便的設計器。。。)

     

     

     

     

     

      本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
      轉(zhuǎn)藏 分享 獻花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多