通过学习MVVM模式,我发现它非常有用并解决了我们每天遇到的许多问题。
但我不明白它与OOP的关系。 OOP总是要求我们封装,关心字段的隐藏(首先在构造函数中初始化它们而不再设置它们)但如果我们用getter / setter属性定义几乎每个模型类,它就违反了OOP规则。 那怎么样呢?可以在真正的MVVM应用程序中定义许多get / set类吗?
谢谢, 雅各布
答案 0 :(得分:3)
嗨,我不认为它打破了OOP的概念。我们通过公共属性公开数据成员。因此数据隐藏在那里,类的用户不知道设置哪个属性将改变场景后面的数据。在属性的setter中,我们可以拥有验证逻辑和任何可以改变类状态的负责方法/属性链。因此封装和数据隐藏就在那里。
由于
答案 1 :(得分:2)
没有与此相比,MVVM是一种OOP设计模式。 属性不破坏OOP原则,它是封装原则的应用;即控制如何加入或修改对象数据。
封装不告诉我们避免对象中的数据修改,它告诉我们要小心它,控制它。
的更多信息答案 2 :(得分:2)
根据上述答案,MVVM不会破坏它所拥有的OOP。理想情况下,您应该通过限制读/写性质并将内聚属性集封装到自己的对象中来减少软件的表面积。这可能会导致您的模型的某些部分是不可变的。但是,如果您有编辑要求,则很难在MVVM中遵循不可变数据模型(DDD /函数编程概念)。
答案 3 :(得分:0)
与此处的其他评论相反,MVVM和OOP是截然相反的方法。 MVVM根本不是面向对象的,以任何方式(无论是直接还是通过“获取器”间接)公开数据都会破坏封装。
例如,如果一个名为ShoppingCart
的对象通过“获取器”要求使用Receipt
对象的数据,则ShoppingCart
现在知道{{1 }},这会增加耦合,并使您的系统对更改的适应能力降低。这称为leaky abstraction。例如,它知道从“ getter”返回的数据的数据类型。如果Receipt
将来会更改数据类型,则Receipt
还必须更改其自己的逻辑以响应数据类型的更改。更糟糕的是,如果ShoppingCart
意识到它可以执行所有任务而不需要发送给Receipt
的数据,并决定删除它,不仅ShoppingCart
不得不再次更改,现在,它无法执行从ShoppingCart
接收到的数据执行的部分任务。
这揭示了有关设计的一些关键问题:为什么Receipt
向ShoppingCart
询问其数据?不管如何返回数据(在这种情况下都是通过“ getter”返回),重要的是内部数据根本是从Receipt
泄漏的,而Receipt
现在与{{1 }}。
面向对象的系统几乎没有对象之间的数据流。假定对象彼此发送消息以执行各种任务。 ShoppingCart
应该要求Receipt
执行必要的任务,因为ShoppingCart
具有执行此任务所需的信息。如果将来Receipt
决定更改自己的内部数据结构,更新其状态,删除或添加新功能等,则Receipt
不会受到它的影响。 Receipt
甚至都不知道ShoppingCart
一开始就被更改了。