ViewModel,Model,MVVM Architecture Problem。
曾几何时我曾经按如下方式定义模型类:
public class Person
{
public string FirstName;
public string LastName;
}
几年后,我明白按如下方式定义模型类更好:
public class Person
{
private string firstName;
private string lastName;
public string FirstName {get{ return firstName;} set{ return firstName; } }
public string LastName {get{ return lastName; } set{ return lastName; } }
}
以及为什么......因为通常它允许更多的多功能性,例如:
public class Person
{
private string firstName;
private string lastName;
public string FirstName {get{ return firstName;} private set{ return firstName; } }
public string LastName {get{ return lastName; } private set{ return lastName; } }
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
几个月后,引入了自动属性,事情变得更容易了:
public class Person
{
public string FirstName {get; set;}
public string LastName {get; set;}
}
多功能性仍然存在:
public class Person
{
public string FirstName {get; private set;}
public string LastName {get; private set;}
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
如果我们在没有私人制定者的情况下去上课,那还有一件好事:
var myInstance = new Person{FirstName = "Che", LastName="Guara"}
到目前为止 - 非常好。
但是现在我们有另一个MVVM真正希望我们使用的演变..(在模型中!)
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string firstName;
private string lastName;
public string FirstName
{
get{ return firstName; }
set
{
firstName = value;
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs("FirstName");
}
}
public string LastName
{
get{ return lastName; }
set
{
lastName = value;
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs("LastName");
}
}
}
所以..好吧..它不像以前那么短,但是可以接受。
但是,如果模型的演变是某种东西,那很自然......
同意“不要重复自己”是一个很好的原则。
在许多情况下,我不需要特定的View-Model类 - 但并不是所有情况。
没关系。
为什么改变对以对象为中心的范式的整体态度是错误的?
例如:
publie interface IPersistable
{
Guid Id {get;set;}
DataAccessLayer Dal {get;set}
void Persist();
void Populate();
}
public class Person : INotifyPropertyChanged, IPersistable
{
public DataAccessLayer Dal;
private Guid Id;
public Guid Id
{
get {return id;}
set
{
id=value;
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs("Id");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private string firstName;
private string lastName;
public string FirstName
{
get{ return firstName; }
set
{
firstName = value;
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs("FirstName");
}
}
public string LastName
{
get{ return lastName; }
set
{
lastName = value;
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs("LastName");
}
}
public void Persist() //assume this is part of IPersistable.
{
Dal.Persist(this);
}
public void Populate() //assume this is part of IPersistable.
{
var t=Populate(Id);
FirstName = t.Firstname;
LastName = t.LastName;
}
}
所以在我可以做的模块中,只是在示例中:
myObj.Persist();
这是一个错误的想法还是一个好主意?良好的建筑或糟糕的建筑?
它仍然存在分离 - 只是用不同的方式写成。
真的把头埋在上面,非常感谢你对此的投入。
感谢。
G.Y。
答案 0 :(得分:2)
关于INotifyPropertyChanged
:MVVM要求您在ViewModels上使用它,因为WPF利用此接口在View及其DataContext
(MVVM中的ViewModel)之间进行数据绑定。除此之外,INPC
只是通知属性更改的界面,可以在任何您喜欢的地方使用。人们通常认为它不应该在模型中实现,这是错误的,但你也不必这样做。您只需要在模型上实现INPC
,如果您想在某个地方使用它,可能最常用于在ViewModel中处理这些更改。如果您的模型仅因ViewModel的操作而发生更改,则无需实现INPC
。
换句话说:该模型不知道它是在MVVM模式中使用的事实。
因此,在设计模型时不要过多考虑整个系统:它提供更改通知:很好,它提供了持久性功能:很好,它是一个非常精细的OOP类。这足以让模型成为MVVM的好模型。
修改强>
问题不是MVVM特定的imo。有意义的是,是否代表一个实体(在这种情况下是一个人),通知属性变化(同样,INPC不是特定于MVVM)和维持持久性是一个类的太多关注。通知和持久性是一种服务功能,您仍然将Dal中的实际逻辑分开。所以,确定为什么不,如果在你的应用程序中单独保存和加载实体是有意义的,你为什么要介意?你不应该这样做的实际问题是什么?当然,一个有两个属性的类会更好,但它总是一个权衡...
简而言之:我认为持有数据,维护这些数据的持久性并通知更改听起来就像一大堆工作要放入课堂。
让我知道这是否令人满意地回答你的问题。