2009-09-18 9 views
5

私はMVPアプリケーション(C#Winforms)を構築しています。私の最初のバージョンはCritique my simple MVP Winforms appです...今、私は複雑さを増やしています。私は、2つの別々のテキストフィールドを2つのビュー/プレゼンターのペアに扱うコードを作りました。それは簡単な例ですが、同じモデルを共有する複数のプレゼンターの詳細を理解することです。MVP Winforms Appでモデルを共有する

私の質問は、モデルについて、次のとおりです。

  1. 私は基本的に何かが変更されたビューを通知するためのモデルが提起したプロパティ変更イベントを使用しています。それは良いアプローチですか?私が100または1000のプロパティを持つポイントに達したらどうなりますか?それはまだその時点で実用的ですか?

  2. 各プレゼンターのモデルを  NoteModel _model = NoteModel.Instance  で正しくインスタンス化していますか?すべてのプレゼンターが同じデータを共有していることを確認したいと思います。

  3. より良いアプローチがあれば、私は提案を開いてる....

私のコードは次のようになります。

NoteModel.cs

public class NoteModel : INotifyPropertyChanged 
{ 
    private static NoteModel _instance = null; 

    public static NoteModel Instance 
    { 
     get { return _instance; } 
    } 

    static NoteModel() 
    { 
     _instance = new NoteModel(); 
    } 

    private NoteModel() 
    { 
     Initialize(); 
    } 

    public string Filename { get; set; } 
    public bool IsDirty { get; set; } 
    public readonly string DefaultName = "Untitled.txt"; 

    string _sText; 
    public string TheText 
    { 
     get { return _sText; } 
     set 
     { 
      _sText = value; 
      PropertyHasChanged("TheText"); 
     } 
    } 

    string _sMoreText; 
    public string MoreText 
    { 
     get { return _sMoreText; } 
     set 
     { 
      _sMoreText = value; 
      PropertyHasChanged("MoreText"); 
     } 
    } 

    public void Initialize() 
    { 
     Filename = DefaultName; 
     TheText = String.Empty; 
     MoreText = String.Empty; 
     IsDirty = false; 
    } 

    private void PropertyHasChanged(string sPropName) 
    { 
     IsDirty = true; 

     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(sPropName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

TextEditorPresenter .cs

public class TextEditorPresenter 
{ 
    ITextEditorView _view; 
    NoteModel _model = NoteModel.Instance; 

    public TextEditorPresenter(ITextEditorView view)//, NoteModel model) 
    { 
     //_model = model; 
     _view = view; 
     _model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged); 
    } 

    void model_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "TheText") 
      _view.TheText = _model.TheText; 
    } 

    public void TextModified() 
    { 
     _model.TheText = _view.TheText; 
    } 

    public void ClearView() 
    { 
     _view.TheText = String.Empty; 
    } 
} 

TextEditor2Presenter.csは、_model.TheTextの代わりに_model.MoreTextで動作する点を除いて、本質的に同じです。

ITextEditorView.cs

public interface ITextEditorView 
{ 
    string TheText { get; set; } 
} 

ITextEditor2View.cs

public interface ITextEditor2View 
{ 
    string MoreText { get; set; } 
} 
+0

+1大きな質問です。私は私の心の中で同じことをしています。 – Marcel

答えて

3
  1. このアプローチは良好です。しかし、もしあなたが何百ものプロパティを持っているのを見ているなら、あなたは神のクラス(アンチパターン)を持っているかもしれないと思います。 100のプロパティを持つ良いクラスはあまりありません。代わりに、モデルをより小さなクラスに分割することを検討してください。さらに、プロパティごとに個別のイベントを持つ必要はありません。モデルがまったく変更された場合は、単一のイベント(変更を説明する情報が含まれている可能性があります)を発生させることができ、ビューはそこから処理できます。
  2. 実際に適用したいと思わない限り、シングルトンパターンを使用しないでください。代わりに、すべてのビューのコンストラクタを変更してモデルのインスタンスを取得します。
+0

1.私は少し誇張していました。私は追跡したい100のものを予見することができました。モデル上の私の考えはカプセル化して集約し、Model.ComplexThing1(10個のプロパティ)とModel.ComplexThing2(4個のプロパティを持つ)などのようになります。 2.私は確信していません私はそれを適用したい。どのように私は知っていますか?モデルの私の理解は、実行時に格納される情報の最終的な情報源であるということです。この場合、モデルのインスタンスは1つだけ必要です。 –

+0

@Keith:そこには、「モデルのインスタンスが1つしか存在してはならない」と「モデルのインスタンスが1つしかない」という違いがあります。工場などで単一のインスタンスを作成するだけでシングルトン(小文字の '!)インスタンスを自由に使用できますが、**必要がある場合はシングルトン(大文字の' S '!)のみを使用します。 –

+0

@Johan Gerell:あなたが "必要なときだけ使う...":この文脈でシングルトンについて何か悪いことはありますか? – Marcel

1

すべてのレイヤーアプリケーションでは、ドメインモデルがすべてのレイヤーを超越するのが普通です。

  1. したがって、私はあなたのプレゼンターが(間違いなくいくつかの並べ替えのコントロールである)ビューにご注意インスタンスを渡す必要がありますし、その後のBindingSourceを通じてデータバインディングを引き継ぐましょう。データバインディングを使用すると、コントロールは自動的にPropertyChangedイベントをリッスンし、それに応じて追加コードを必要とせずに更新します。イベントベースの通知は、変更を気にするオブジェクトだけがアクションを取るため(多くのオブジェクトが不必要にアクションを実行するのに対して)、監視されているプロパティの数に関係なく、ここで適切に使用されます。

  2. 通常、エンティティインスタンスは下位レイヤから取得されます。たとえば、Noteインスタンスを返すサービスを実装することができます。ノート#3のサービスを要求するたびに、それは永続データから作成されたノートの同じインスタンスを返します。さらに、ビジネスレイヤーに別のアイテムを追加してプレゼンターを補うこともできます。これは、WorkItemまたはControllerを呼び出すことができます。すべてのプレゼンターがWorkItemインスタンスを参照して、ユーザーが作業するノートの現在のインスタンスを取得できます。

私はコンポジットアプリケーションブロック(またはCAB)は、スマートクライアントアプリケーションを作成するために、これらのパターンを使用する方法の例を検討して検討します。それはすべての設計パターンとオブジェクト指向の原則であり、実装には十分な価値があります。

1
  • 質問1:INotifyPropertyChangedの実装は私にとっては良い考えです。おそらくあなたはいくつかのクラスに多くのプロパティを分割します。
  • 質問2:私は現在、複数のプレゼンターとMVPモデルを共有するためにシングルトンパターンを使用しています。私はこれまでのところ、私のモデルのインスタンスが本当に1つしかないことを保証しています。
関連する問題