WPF的MVVM中的Model与ViewModel的结构思路总感觉不对
请教高手关于Model与ViewModel的设计问题。
Model中存在各种关联关系,比如:Company中包含List<Department>,而department中包含List<Team>,Team中包含List<Employee>,这样就会形成层次结构。这样为了不把model直接暴露给view,要通过viewmodel来隔离,这样在viewmodel中就把model中的属性包装一下再暴露给view。这样,viewmodel中也会形成与model中相同或相似的层次结构,感觉起来把问题弄复杂了,感觉哪里不对似的。例如如下代码:
class Company
{
List<Department> Departments{get;set;}
public string CompanyName{get;set;}
....//other properties and methods
}
class Department
{
List<Team> Teams{get;set;}
public string DepartmentName{get;set;}
....//other properties and methods
}
class Team
{
List<Employee> Employes{get;set;}
public string TeamName{get;set;}
....//other properties and methods
}
class Employee
{
public string EmployeeName{get;set;}
}
那么在设计ViewModel的时候,由于view显示的需要,是不是都要弄一个对应的viewmodel类呢?比如:
class CompanyViewModel:INotifyPropertyChanged
{
public CompanyViewModel(Company company)
{
_company=company;
}
private Company _company;
private ObservableCollection<DepartmentViewModel> _department;
public ObservableCollection<DepartmentViewModel> Departments
{
get
{
if(_department==null)
_department=new ObservableCollection<DepartmentViewModel>();
foreach(var d in _company.Departments)
_department.Add(new DepartmentViewModel(d));
return _department;
}
}
public string CompanyName
{
get
{return _company.CompanyName;}
set
{
_company.CompanyName=value;
OnPropertyChanged("CompanyName");
}
}
....//其它属性、方法、字段、event等省略
}
class DepartmentViewModel:INotifyPropertyChanged
{
public DepartmentViewModel(Department department)
{
_department=department;
}
private Department _department;
private ObservableCollection<TeamViewModel> _teams;;
public ObservableCollection<TeamViewModel> Teams
{
get
{
if(_teams==null)
_teams=new ObservableCollection<TeamViewModel>();
foreach(var t in _department.Teams)
_teams.Add(new TeamViewModel(t));
return _teams;
}
}
public string DepartmentName
{
get
{return _department.DepartmentName;}
set
{
_department.DepartmentName=value;
OnPropertyChanged("DepartmentName");
}
}
....//其它属性、方法、字段、event等省略
}
class TeamViewModel:INotifyPropertyChanged
{
public TeamViewModel(Team team)
{
_team=team;
}
private Team _team;
private ObservableCollection<EmployeeModel> _employees;;
public ObservableCollection<EmployeeModel> Employees
{
get
{
if(_employees==null)
_employees=new ObservableCollection<EmployeeModel>();
foreach(var e in _team.Employees)
_employees.Add(new EmployeeModel(e));
return _employees;
}
}
public string TeamName
{
get
{return _team.TeamName;}
set
{
_team.TeamName=value;
OnPropertyChanged("TeamName");
}
}
....//其它属性、方法、字段、event等省略
}
class EmployeeViewModel:INotifyPropertyChanged
{
public EmployeeViewModel(Employee employee)
{
_employee=employee;
}
private Employee _employee;
public string EmployeeName
{
get
{return _employee.EmployeeName;}
set
{
_emplpyee.EmployeeName=value;
OnPropertyChanged("EmployeeName");
}
}
....//其它属性、方法、字段、event等省略
}
在以上的代码中,Model层和ViewModel层都形成了相同的层次结构,结构更加复杂了,但是问题还不仅如此:
如果所有的移动对象(比如在EmployeeA发生调动,需要从TeamA调动到TeamB,这样一个业务逻辑,如果放在ViewModel层去写,则可以放置在DepartmentViewModel中去完成逻辑,即把teamA中的这个雇员移动到teamB中,移动结束后ViewModel层是知道改变的,ObservableCollection会自动通知View层改变)。如果放在Model层去写EmployeeA的调动逻辑,然后通过ViewModel来调用这样的逻辑,则ViewModel层不知道Emplpyee,view是不会发生改变的,能想到的方式是把Model都实现INotifyProperty接口,并给属性添加上OnPropertyChanged方法调用,同时将Model对象中的集合属性由List改为ObservableCollection<>,并在对应的ViewModel中订阅PropertyChanged事件和CollectionChanged事件,当model的属性发生改变时,对应的ViewModel中通过方法来同步进行改变。
总结下:(1)如果在ViewModel中写业务逻辑,Model的所有属性改变必须由ViewModel来完成,那么感觉viewmodel对象中的逻辑太多,又不像是MVVM所说的VM的功能,程序对象多了以后会把ViewModel弄得特别复杂,就像是PresentationLogic和BusinessLogic都由VM承担了似的,Model层只是写了一些Entity似的。
(2)如果业务逻辑放在Model中写,则在一个Model对象中改变了属性的话,就需要为Model实现INotifyPropertyChanged接口和使用ObservableCollection集合类,然后由ViewModel订阅Model的PropertyChanged和CollectionChanged事件实现同步改变并通知View发生响应。这样感觉自来就弄得特别复杂,必须小心翼翼地考虑没一个Model属性改变如果通过事件来通知ViewModel发生响应,并且性能也会受到很多影响。
问题:总感觉这两种途径都有问题,不知大家都是怎么考虑的呢?还请前辈分享心得,不胜感激,谢谢[/b]