如果BusinessObject and person classes(以及他们的 VM 类)是抽象的,
public abstract class BusinessObjectViewModel : ViewModelBase
{
protected abstract BusinessObject BusinessObject { get; }
protected BusinessObject Model { get { return this.BusinessObject; } }
}
public abstract class PersonViewModel : BusinessObjectViewModel
{
protected abstract Person Person { get; }
protected new Person Model { get { return this.Person; } }
protected override sealed BusinessObject BusinessObject
{
get { return this.Model; }
}
}
public class CustomerViewModel : PersonViewModel
{
protected new Customer Model { get; set; }
protected override sealed Person Person
{
get { return this.Model; }
}
}
public class EmployeeViewModel : PersonViewModel
{
protected new Employee Model { get; set; }
protected override sealed Person Person
{
get { return this.Model; }
}
}
这样,每个衍生的VM等级都通过实施抽象属性和隐藏基本等级的模型属性,为其基本VM模型属性提供价值,因此,每个VM等级都使用适当类型的模型属性(因此不需要铸件)。
这种办法的利弊在于:
效益:
补缺 :
- Works only if base classes (BusinessObjectViewModel and PersonViewModel) are abstract because there must exist an abstract property that is implemented by the derived class and provides a Model instance to these base classes.
- Model property should not be accessed in the base class constructors, because constructor chaining goes from base class to the most derived class. The most derived class constructor will set Model, so base class constructors are called to early to see it. This can be avoided by passing Model as a parameter through constructors.
- BusinessObject and Person properties are unnecessary seen by the derived classes. EditorBrowsableAttribute might help here for Intellisense, but only when code is used by another assembly in different Visual Studio solution (this is Visual Studio specific behavior).
- Performance. When base classes access Model, code will go through a chain of virtual properties. But since since implemented abstract properties are marked as sealed, virtual table lookup should not be so much performance degrading.
- Doesn t scale nicely. For deep class hierarchies code would contain many unnecessary members.
另一种办法是:
public class BusinessObjectViewModel : ViewModelBase
{
protected BusinessObject Model { get; private set; }
public BusinessObjectViewModel(BusinessObject model)
{
this.Model = model;
}
}
public class PersonViewModel : BusinessObjectViewModel
{
protected new Person Model { get { return (Person)base.Model; } }
public PersonViewModel(Person model)
: base(model)
{
}
}
public class CustomerViewModel : PersonViewModel
{
protected new Customer Model { get { return (Customer)base.Model; } }
public CustomerViewModel(Customer model)
: base(model)
{
}
}
public class EmployeeViewModel : PersonViewModel
{
protected new Employee Model { get { return (Employee)base.Model; } }
public EmployeeViewModel(Employee model)
: base(model)
{
}
}
效益:
- Base classes do not need to be abstract.
- Model can be accessed through base class constructors.
- No unnecessary additional properties.
补缺 :
基于这一分析,我将采用第二种选择,因为纠正其唯一的缺点,即铸造性能,将是不必要的微优化,在WPF中将不明显。