我们的许多网页都使用自定义视图模型,这些模型基本上是NHibernate映射实体的缩减版本。
当您拥有一组全局实体时,重复使用一小部分以实体为中心的业务逻辑非常简单,因为逻辑可以添加到实体中。但是,一旦我们拥有特定于视图的视图模型,这就变得更难了。
这是一个人为的例子:
// 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,它需要接受实体和视图模型都实现的接口。这将导致重复代码的激增,因为我们现在必须将每个属性写出三次。还有什么可以做的?
答案 0 :(得分: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
});
}
}