2009-08-31 8 views
0

(多く編集)抽象メンバでいくつかのクラスがあります。抽象メンバの具体的な型は、ユーザの入力に基づいてクラスインスタンスで決定される。ただし、2番目のメンバの具体的な型は、最初のメンバに依存する場合があります。複合構造化オブジェクトモデルのMVPの使用

私はMVPデザインパターンを念頭に置いて何かをしようとしています。私はPresenterがモデルのCtorに代理人を渡し、彼(Ctor)がクラスのインスタンス化に必要な情報を要求するのに使うことを教えました。私はそれが良い考えであるかどうか分からない。ここに私が書いたものがあります:

// In the Model : 
public class Model 
{ 
    public E Element1; 
    public E Element2; 

    public Model(CustomCtor<ModelElement, IModelElement> GetModelElement) 
    { 
     this.Element1 = (E)GetModelElement(ModelElement.E, null); 
     this.Element2 = (E)GetModelElement(ModelElement.E, null); 
     //Element2 does not depend on Element1 in this case though. 
    } 
} 

public abstract class E : IModelElement { } 

public class EA : E 
{ 
    public string Element1; 
    public EA(string Element1) { this.Element1 = Element1; } 
} 

public class EB : E 
{ 
    public int Element1; 
    public EB(int Element1) { this.Element1 = Element1; } 
} 

public interface IModelElement { } 

public enum ModelElement { E, EA, EB } 

// In the Presenter : 
public class Presenter 
{ 
    View.View view1; 

    public Presenter() { } 
    public void SetView(View.View view) { this.view1 = view; } 

    public Model.Model MakeModel() 
    { 
     CustomCtor<ModelElement, IModelElement> GetModelElement = new CustomCtor<ModelElement, IModelElement>(GetModelElement<ModelElement, IModelElement>); 
     return new Model.Model(GetModelElement); 
    } 

    private Model.IModelElement GetModelElement<ModelElement, Tout>(Model.ModelElement ME, object obj) 
    { 
     switch (ME) 
     { 
      case Model.ModelElement.E: 
       return MakeE(); 
      // One case per Model.ModelElement 
      default: 
       throw new Exception("ModelElement not implemented in the Presenter."); 
     } 
     return default(Model.IModelElement); 
    } 

    private E MakeE() 
    { 
     switch (view1.AskEType()) 
     { 
      case 1: 
       return MakeEA(); 
      case 2: 
       return MakeEB(); 
      default: 
       throw new Exception(); 
     } 
    } 

    private EA MakeEA() { return new EA(view1.AskString("EA.Element1 (String)")); } 
    private EB MakeEB() { return new EB(view1.AskInt("EB.Element1 (Int)")); } 
} 

// Shared to the Model and the Presenter : 
public delegate TOut CustomCtor<EnumType, TOut>(EnumType Enum, object Params) where EnumType : struct; 

// In the View : 
public class View 
{ 
    public int AskEType() 
    { 
     Console.WriteLine(string.Format("Type of E : EA(1) or EB(2)?")); 
     return int.Parse(Console.ReadLine()); 
    } 
    public string AskString(string Name) 
    { 
     Console.Write(string.Format("{0} ? ", Name)); 
     return Console.ReadLine(); 
    } 
    public int AskInt(string Name) 
    { 
     Console.Write(string.Format("{0} ? ", Name)); 
     return int.Parse(Console.ReadLine()); 
    } 
} 

//In the Program : 
class Program 
{ 
    static void Main(string[] args) 
    { 
     View.View view1 = new View.View(); 
     Presenter.Presenter presenter1 = new Presenter.Presenter(); 

     presenter1.SetView(view1); 
     presenter1.MakeModel(); 
    } 
} 

それは意味がありますか?私がやろうとしていることの名前はありますか? (「奇妙なこと」の横に) あなたが読んでおくべきデザインパターンが分かりましたか? 私はBuilderデザインパターンとMVPを混在させることについて教えましたが、私はそれをどうやって行うのかは分かりません。

おかげ

答えて

1

が、私は確かではないよ、これはあなたがについて尋ねるものですが、私はあなたのモデルから分離されたビューを維持しようとしていると仮定しています。それが本当にあなたがしようとしているものなら、私はあなたのアプローチが非常に複雑すぎると思います。このビューは単にプレゼンテーションとフィードバックのメディアです。実際にはモデルについて何も知る必要はなく、ある種の財産袋に簡単なデータを使うように設計することができます。これにより、よりクリーンな分離が可能になりますが、データのレンダリングや表示の維持が困難になることがよくあります。

最初の質問は、あなたの見解を完全にあなたのモデルから隔離したままにするために多大な努力を費やすのに本当に価値があるのでしょうか?あなたは本当に分離して何を得ていますか?

本当に分離が必要な場合は、ビューとプレゼンターの役割を理解していることを確認してください。ビューはダムです...それは何も知らず、何もしません。それは情報とフォームを提示します。ブラウザは、ユーザが要求したコマンドを発行する。プレゼンターはコマンドを処理し、データをそのビューに転送します。 「プレゼンターがビューを求める」という概念は、一般的には間違っています。プレゼンターはコマンド(http要求)を直接処理する必要があるため、特定のコマンドに関するすべての詳細を把握する必要があります。ビューをレンダリングする時間が来たら、プレゼンターは、ビューに必要なあらゆる形式のデータをビューに提供する必要があります。ビューにオブジェクトモデルを知らせたくない場合は、ビューにプロパティを作成するかデータ自体を格納するか、必要なデータをカプセル化するビュー固有のモデルを作成します。

編集:

あなたの更新を読みました。私は今あなたの問題を少しは理解していると思います。まず、私が遠くに行く前に、あなたは少し責任を再編成する必要があります。現時点では、入力を処理するビューがビューの責任になります。それは、「見解」の目的と概念の腐敗の少しです。 MVPとMVCの両方で、ビューはできるだけ "ダム"であると考えられ、実際に何かを処理する責任を負うべきではありません。コマンド、アクション、入力などはすべてコントローラまたはプレゼンターの責任であるべきです。

ビューは実際にはコンソールアプリケーションであり、Webフォームアプリケーションではなく(私の元々の想定だった)、MVCは実際にはあなたのニーズに適していると思う。 MVPはASP.NET WebFormsの欠点を回避するための優れたソリューションですが、MVCとは別の懸念を助けるほど強力ではありません。 MVCパターンは、もともとコンソールタイプのアプリケーション用に設計されたものです。コントローラーはセントラル入力ハンドラーになり、コマンドハンドラーとモデルにコマンドを発行します。ビューは純粋であり、形成するのは真実です...レンダリング情報だけです。

あなたは、私が理想的であると思われ、MVCアプローチを使用することはできませんし、MVPを使用しなければならない理由はいくつかの理由がある場合、私はあなたがあなたの現在の実装を修正することができる方法の詳細なアドバイスを提供することができます。しかし、私は強くパターンはもともとあなたが解決するための...コンソールアプリケーションにしようとしている非常に問題を解決するために設計されたこととして、MVCを使用してに探してお勧めします。

+0

私は、視聴者がコンソールであることと、このコードを書いたが、実際には、私は本当のビューはWinフォームとWebフォームとなりますので、「たIView」を使用する予定。また、入力はので、私は、各コンポーネントの種類のいくつかのユーザーコントロールを作るために計画された(主にドロップダウンと数値テキストボックス)もう少し複雑になります。また、プレゼンターがビューから直接情報を読み取るようにしました(ビューの戻り値を作成しない)。その追加情報があれば、MCPの代わりにMVCを利用するように私に提案しますか?あなたのご意見ありがとうございます、本当に感謝しています。 – Tipx

+0

WebFormsでは、MVPが役立ちます。 WebFormsのMVCをそのまま作成するのは難しいです。 WinFormsとWebFormsは非常によく似ているため、MVPはWindowsフォームでも動作します。しかし、それは本当に多くの画像を変更しません。ビューが "ダム"で、プレゼンターが入力を処理することは非常に重要です。プレゼンターは、プレゼンターから最初に入力する必要があるため、何も表示する必要はありません。 IView実装は、プレゼンターにデータをビューにプッシュする機能を提供しますが、それ以外の機能は提供しません。 – jrista

+0

ありがとう、私はいくつかのことを試している間、それを念頭に置いておきます。私はプログラミングでどれ形成の隣を持っていると私は多くのデザインパターンを見ていないが、私はあなたのアドバイスを私にいくつかのトラップを惜しまだろうに疑いはありません! (でも、私は間違いをするだろうが、彼らから学ぶだろう。)ありがとう。 – Tipx