模型演进架构设计查询

本文关键字:查询 模型 | 更新日期: 2023-09-27 18:08:14

ViewModel,Model,MVVM架构问题。

从前,我曾经定义一个模型类如下:

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");
    } 
  }
}

所以。。好的。它不像以前那么短了,但它是可以接受的。

但如果模型的演变是自然的。。

大家一致认为"不要重复自己"是一个很好的原则。

在许多情况下,我不需要特定的视图模型类,但并非在所有情况下都需要。

没关系。

为什么改变对以对象为中心的范式的整个态度是错误的?

例如:

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.

模型演进架构设计查询

关于INotifyPropertyChanged:MVVM要求您在ViewModels上使用它,因为WPF利用此接口在View及其DataContext(MVVM中的ViewModel(之间进行数据绑定。除此之外,INPC只是一个用于通知属性更改的接口,可以在任何您喜欢的地方使用。人们通常认为它不应该在模型中实现,这是错误的,但你也不必这样做。如果你想在某个地方使用它,你只需要在模型上实现INPC,可能最常见的情况是在ViewModel中处理这些更改。如果您的模型只是由于ViewModel的操作而更改,则不需要实现INPC

换句话说:该模型不知道它在MVVM模式中使用的事实。

因此,在设计模型时,不要过多考虑整个系统:它提供了更改通知:好,它提供了持久性函数:好,这是一个非常好的OOP类。这足以使该模型成为MVVM的一个好模型。

编辑:

这个问题不是特定于MVVM的imo。对于一个类来说,代表一个实体(在这种情况下是一个人(、通知属性更改(同样,INPC不是特定于MVPM的(和保持持久性是否太多是有意义的。通知和持久性是一种服务功能,您仍然可以在Dal中分离实际的逻辑。那么,为什么不呢?如果在应用程序中单独保存和加载实体是有意义的,你为什么会介意呢?你真正关心的是什么?为什么你不应该这么做?当然,一个有两个属性的类会更好,但这总是一种权衡。。。

简言之:我认为保存数据、保持数据的持久性和通知更改听起来像是一个很好的作业包。

让我知道这是否令人满意地回答了你的问题。