2013-07-07 20 views
3

很多我們的頁面使用自定義視圖模型,這些模型基本上是NHibernate映射實體的縮減版本。在使用ViewModels而不是實體時DRY的策略

當您擁有一組全局實體時,重複使用以實體爲中心的小型商業邏輯很簡單,因爲可以將邏輯添加到實體中。但是,一旦我們擁有特定於視圖的視圖模型,就會變得越來越困難。

這是一個人爲的例子:

// Entity 
public class Sale : Entity 
{ 
    public Guid Id { get; set; } 
    public decimal Tax { get; set; } 
    public decimal SalePrice { get; set; } 
    public int TotalPrice 
    { 
     get { return Tax + SalePrice; } 
    } 
    ... more properties ... 
} 

// View model 
public class SaleView 
{ 
    public Guid Id { get; set; } 
    public decimal Tax { get; set; } 
    public decimal SalePrice { get; set; } 
} 

public class Controller 
{ 
    public Action ViewSale(Guid id) 
    { 
     return Session.Query<Sale>() 
      .Where(x => x.Id == id) 
      .Select(x => new SaleView 
       { 
        Id = x.Id, 
        Tax = x.Tax, 
        SalePrice = x.SalePrice 
       }); 
    } 
} 

在這個例子中,你用什麼樣的戰略來重新使用當前的實體進行的「TotalPrice」如何計算?

您可以使「TotalPrice」成爲某個地方的靜態方法,並讓它接受稅收和銷售價格作爲參數,但這會導致相當醜陋,不靈活的代碼,特別是隨着屬性數量和屬性之間關係的增長。您可以創建一個單獨的「TotalPriceCalculator」類,但要處理ViewModel,它需要接受實體和視圖模型實現的接口。這將導致重複代碼的激增,因爲我們現在必須將每個屬性寫出三次。還有什麼可以做的?

回答

2

您可以定義一個總價格策略,您可以在您的實體和視圖模型中注入該策略。您注入總價政策的事實使其更加靈活。您可以輕鬆實施其他政策。它看起來像這樣:

public interface ITotalPricePolicy 
{ 
    decimal TotalPrice(decimal tax, decimal salesPrice); 
} 

public class TotalPricePolicy : ITotalPricePolicy 
{ 
    public decimal TotalPrice(decimal tax, decimal salesPrice) 
    { 
     return tax + salesPrice; 
    } 
} 

public class Sale : Entity 
{ 
    public Guid Id { get; set; } 
    public decimal Tax { get; set; } 
    public decimal SalePrice { get; set; } 

    public decimal TotalPrice(ITotalPricePolicy totalPricePolicy) 
    { 
     return totalPricePolicy.TotalPrice(Tax, SalePrice); 
    } 
} 

public class SaleViewModel 
{ 
    private readonly ITotalPricePolicy _totalPricePolicy; 

    public SaleViewModel(ITotalPricePolicy totalPricePolicy) 
    { 
     _totalPricePolicy = totalPricePolicy; 
    } 

    public Guid Id { get; set; } 
    public decimal Tax { get; set; } 
    public decimal SalePrice 
    { 
     get { return _totalPricePolicy.TotalPrice(Tax, SalePrice); } 
    } 
} 

public class HomeController : Controller 
{ 
    private readonly ITotalPricePolicy _totalPricePolicy; 

    public HomeController(ITotalPricePolicy totalPricePolicy) 
    { 
     _totalPricePolicy = totalPricePolicy; 
    } 

    public Action ViewSale(Guid id) 
    { 
     return Session.Query<Sale>() 
      .Where(x => x.Id == id) 
      .Select(x => new SaleView(_totalPricePolicy) 
      { 
       Id = x.Id, 
       Tax = x.Tax 
      }); 
    } 
} 
+0

+1,這是一種稱爲策略或策略模式的已知模式。你可以在http://en.wikipedia.org/wiki/Strategy_pattern看到更多 – epitka

相關問題