假設以下基線設計:我有一個類CarElement,其中包含與汽車的視覺表示和資料模型/邏輯表示相關的屬性和方法:
class carElement
{
// UI related properties and methods:
public Size DrawSize { get; set; }
public Point Location { get; set; }
public void Draw()
{
// do something...
}
// data model / logic related properties and methods:
public double weight { get; set; }
public string manufacturer { get; set; }
public double CalculatePrice()
{
// do something...
return 0;
}
}
該類的用法如下: 將多個實體carElement繪制到某個畫布上。單擊每個繪制的汽車會使用 顯示該汽車在屬性網格中的屬性propertygrid.SelectedObject = InstanceOfcarElement。
在我看來,這種設計是有缺陷的,因為資料模型和可視化表示在類設計中沒有分開。我想改進面向 MVC 的設計,我正在尋求有關良好設計決策的建議。
我目前對此的看法是將上面的類carElement分成以下兩個類。
class carUIElement // organizes visual representation of a car
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
private carDataElement linkedCarDataElement;
public void Draw()
{
// do something...
}
}
class carDataElement // organizes data model organization of a car
{
public double weight { get; set; }
public string manufacturer { get; set; }
private carUIElement linkedCarUIElement;
public double CalculatePrice()
{
// do something...
return 0;
}
}
使用這種方法,我不清楚以下幾點:
carUIElementshould know thecarDataElementit is linked to, and vice versa. Are there better design approaches to this than the simple linking in above Code?- How would I best show both the UI and data model properties on the property Grid, when the drawn UIElement is clicked?
Is the overall approach viable? What about the above open points? I am missing the experience to judge that, so I would be grateful for your comments. Thank you.
uj5u.com熱心網友回復:
好吧,雖然我們應該始終小心不要將東西過度智能化,畢竟我們作為程式員比藝術家更像是泥瓦匠,即使巴黎圣母院只是一個建筑而不是藝術,也不總是需要過高的裝飾和隔音室,假設下一個版本會和上一個一樣盛大:)
我是什么意思?我建議 MVC 實用主義,所以如果在程式的早期階段,它可以有 ui 模型,有時也稱為資料傳輸物件,與邏輯模型相同,這本身不是反模式 imo。顯然,一旦構建了 ui,我們就開始發布具有假定構造的實體,當它開始限制產品的開發時,它是如何呈現的,通常是當您需要更多與 ui 相關的資訊時,存盤在物體中,然后您可以通過創建 DTO 模型物件并使用初始模型來鎖定介面。所以我知道你要去哪里以及為什么你可能想要將它分開。
再說一次,我們經常有 Web 前端,尤其是使用 mvc,然后大多數情況下它將不再是資料系結視圖,而是像 Angular、React、Vue 甚至 Blazor 之類的 MVVM 之類的東西,如果出于某種原因你可能想要它,或者傳統的 Razor頁,真的嗎?在新的發展??如果只有序列化的 JSON 版本可用于您的視圖引擎,我盡量不將任何內容放入 DTO 類中。因此,當現代化發生時,您的控制器/api 不必主要更改。
因此,單獨的單獨類與資料訪問或傳輸類中的邏輯無關,我的建議將是以下內容,但最終會提出您的問題:
a) 如果您使用它來加載資料模型中的導航屬性,例如使用物體框架,則它是必需的。在您的 UI 型別中,頻率是關鍵,通常我們喜歡將所有資料推送到點中,這樣它們就不需要執行任何其他操作,但是如果類正在被序列化和反序列化并且您使用 AutoMapper 之類的工具移動到從,如果您在像 WPF 這樣的 Windows 客戶端中,嘿您的模型已經在客戶端上并且已經為 MVVM 加載,那么您處于一個更好的位置,您可能不會誠實地關心前端型別,直到他們需要改變。
b) 問題是你是否總是想同時顯示這兩個元素,或者你可以隱藏 cardata 元素直到他們要求它,這將決定讓 DTO 包含來自關系的資料或只包含外鍵的選擇,并有一個額外的可用的查找方法imo。
所以建議簡短:
/// <summary>
/// Drawing is a separate concern of the application
/// </summary>
class DrawManager
{
public void DrawCar(CarBase car) { }
}
/// <summary>
/// So is calculating prices
/// </summary>
class PriceManager
{
decimal CalculateCarPrice(CarBase car) { throw new NotImplementedException(); }
}
/// <summary>
/// The 2 classes share properties, invent a base class to abide by the DRY principle
/// </summary>
class CarBase
{
public Size DrawSize { get; set; }
public Point Location { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carElement : CarBase
{
carDataElement CarData { get; set; }
}
/// <summary>
/// Now they are identical
/// </summary>
class carUIElement : CarBase
{
carDataElement linkedCarDataElement;
}
/// <summary>
/// The data about a car, in RDBMS typically normalized into a seperate entity like you have,
/// does UI really need any of them? Is it always needed when other members are accessed?
/// </summary>
/// <remarks>
/// we could choose to have the data model have a navigation property and then let the ui member not have it and give it a method to ackquire it,
/// but then that shouldn't get done to early and well if it always needs it, it is not yet a seperate datatype justification for the ui aspect
/// </remarks>
class carDataElement
{
public double weight { get; set; }
public string manufacturer { get; set; }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/330947.html
標籤:c# oop model-view-controller class-design propertygrid
下一篇:如何在不覆寫的情況下填充陣列
