Was wird bei der Verwendung wiederverwendbarer Geschäftsobjekte als bewährte Methode beim Erstellen von Ansichtsmodellen angesehen?
Wir verwenden ein Objekt, das wir aufrufen Builder
, um unsere Ansichtsmodelle zu erstellen. Ein Builder für jede logische Ansichtseinheit (Bestellungen, Benutzer usw.), wobei jede Einheit eine Reihe verschiedener Ansichtsmodelle enthalten kann (Bestellungen enthalten Zusammenfassung, Auftragspositionen usw.).
Ein Builder kann Daten durch ein oder mehrere Standardgeschäftsobjekte ziehen, um ein Ansichtsmodell zu erstellen.
Was ist die bessere Vorgehensweise bei der Verwendung von Geschäftsobjekten / -modellen in Ansichtsmodellen?
Ansatz 1
Verwendung von Geschäftsobjekten im Ansichtsmodell zulassen?
//Business object in some library
public class Order
{
public int OrderNum;
public int NumOrderLines;
//...
}
//Order builder in website
public class OrderBuilder
{
public OrderSummary BuildSummaryForOrder(int OrderNum)
{
Some.Business.Logic.Order obOrder = Some.Business.Logic.GetOrder(OrderNum);
//Any exception handling, additional logic, or whatever
OrderSummary obModel = new OrderSummary();
obModel.Order = obOrder;
return obModel;
}
}
//View model
public class OrderSummary
{
public Some.Business.Logic.Order Order;
//Other methods for additional logic based on the order
//and other properties
}
Ansatz 2
Nehmen Sie nur die erforderlichen Daten aus den Geschäftsobjekten
//Business object in some library
public class Order
{
public int OrderNum;
public int NumOrderLines;
//...
}
//Order builder in website
public class OrderBuilder
{
public OrderSummary BuildSummaryForOrder(int OrderNum)
{
Some.Business.Logic.Order obOrder = Some.Business.Logic.GetOrder(OrderNum);
//Any exception handling, additional logic, or whatever
OrderSummary obModel = new OrderSummary()
{
OrderNum = obOrder.OrderNum,
NumOrderLnes = obOrder.NumOrderLines,
}
return obModel;
}
}
//View model
public class OrderSummary
{
public int OrderNum;
public int NumOrderLines
//Other methods for additional logic based on the order
//and other properties
}
Ich kann die Vor- und Nachteile beider erkennen, aber ich frage mich, ob es einen akzeptierten Ansatz gibt. In Ansatz 1 gibt es keine Duplizierung von Code um die Modelle herum, aber es entsteht eine Abhängigkeit von der Geschäftslogik. In Ansatz 2 verwenden Sie nur die für die Ansicht erforderlichen Daten, duplizieren jedoch den Code um die Modelle.
quelle
Option 1 ist vorzuziehen, da Code-Duplikationen vermieden werden. Das ist es.
Wenn sich das Domänenmodell erheblich ändert, ist es fast sicher, dass sich die Ansicht trotzdem ändern muss. Mit Option 2 müssen Sie dann das Ansichtsmodell UND den Builder sowie die Ansicht selbst ändern. So etwas ist ein absolutes Gift für die Wartbarkeit. YAGNI.
Der Zweck eines separaten Ansichtsmodells besteht darin, den Status, der nur für die Ansicht (z. B. welche Registerkarte derzeit ausgewählt ist) vom Geschäftsmodell getrennt ist, getrennt zu halten. Die Geschäftsdaten selbst sollten jedoch wiederverwendet und nicht dupliziert werden.
quelle
Prinzipien und Mantras sind manchmal wertvoll, um das Design zu leiten ... aber hier ist meine praktische Antwort:
Stellen Sie sich vor, Ihre Ansichtsmodelle werden in JSON oder XML serialisiert. Wenn Sie versuchen, Ihre Domain-Modelle zu serialisieren, kommt es zu einem schrecklichen Textgewirr, bei dem höchstwahrscheinlich Probleme mit Zirkelverweisen und anderen Problemen auftreten.
Der Zweck eines Ansichtsmodells besteht nicht darin, Domänenmodelle zu gruppieren, damit die Ansicht sie verwenden kann. Stattdessen sollte das Ansichtsmodell ein völlig flaches Modell der Ansicht sein ... das, was Sie tatsächlich auf dem Bildschirm betrachten. Ihre Ansichtslogik sollte sich nur mit der Strukturierung der im Ansichtsmodell vorhandenen Daten befassen.
Idealerweise sollte Ihr Ansichtsmodell fast ausschließlich aus vorformatierten Zeichenfolgen bestehen. Denken Sie darüber nach ... Sie möchten nicht einmal eine DateTime oder Dezimalstelle in Ihrem Ansichtsmodell, weil Sie dann die Formatierungslogik in C #, Javascript, Objective-C usw. nicht mehr ausführen können.
quelle