2009-08-31 49 views
0

(編輯很多)我已經得到了一些類與文摘成員。抽象成員的具體類型應根據用戶的輸入在課堂實例中確定。但是,第二個成員的具體類型可能取決於第一個成員。使用MVP的複合結構的對象模型

我試圖做一些事情保持MVP設計模式的初衷。我教過如何讓Presenter將代表傳遞給Model的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

我用Viewer作爲控制檯編寫了這段代碼,但實際上我打算使用「IView」,因爲真正的視圖將是WinForm和WebForm。另外,輸入會稍微複雜一些(主要是下拉菜單和數字文本框),所以我打算爲每個組件類型製作一些用戶控件。我還計劃讓Presenter直接從視圖中讀取信息(而不是使視圖返回值)。考慮到附加信息,你是否仍然建議我使用MVC而不是MCP?感謝您的意見,非常感謝。 – Tipx 2009-09-01 02:51:28

+0

使用WebForms,MVP會很有幫助。按照原樣創建WebForms的MVC是很困難的。 MVP也可以使用Windows窗體,因爲WinForms和WebForms的工作方式非常相似。但是,這並沒有真正改變畫面。這是非常重要的,這個觀點是「愚蠢的」,並且演示者處理輸入。主持人不應該問任何問題,因爲輸入應該先通過主持人,而不是其他方式。 IView的實現應該讓主持人有能力將數據推送到視圖中,而不是其他的。 – jrista 2009-09-01 03:16:35

+0

謝謝,我會記住這一點,而我會嘗試一些事情。我在編程方面有着無人能及的地位,我還沒有看到太多的設計模式,但我毫不懷疑你的建議會讓我避免一些陷阱! (即使如此,我會犯錯誤,但會向他們學習。)謝謝。 – Tipx 2009-09-01 03:30:52