因为Swift/Objective支持编写扩展,所以我在模型上的扩展类中编写我的" ViewModel“属性,并在通常使用ViewModel的地方使用这个扩展。
我知道扩展不能有存储属性。但是,大多数MVVM体系结构都不推荐在ViewModel中存储属性(除了用于缓存的属性)。
维护单独的ViewModel对象的主要问题是使它与模型同步。是的,有很多第三方框架可以帮助同步使用反应式编程技术。但是对于可以解决的问题,简单地使用一个扩展,为什么使用一个沉重的框架来实现同样的目标呢?
我还没有遇到基于扩展的MVVM体系结构的障碍。你们中是否有人尝试过这种方法,并转向了一种反应式的编程体系结构?
发布于 2017-06-23 15:31:42
我在扩展方法方面的糟糕经验是我2016年3月在纽约iOSoHo的演讲的第一个也是最重要的部分的基础。我说的大部分关于扩展的内容都不在幻灯片中。扩展方法有几个问题:
name,然后再加上firstNameOnly等等,你很可能会遇到碰撞。当然,如果你想这样做的话,一个模型只能以一种方式遵守协议。使用ViewModel,这些重要的情况变得微不足道。(在我所说的“命令”中,我称之为“命令”,因为它们完全符合命令的“四人帮”设计模式定义;definition也称为Action,即UIAlertAction)。
我采用的方法是,"ViewModel“应该是轻量级的、不可变的、通过单向数据流分发的。它们有存储的属性,但这只是为了移动数据,VM本身是不可改变的和一次性的。这类似于脸书在2017年3月iOSoHo上提到的方法,尽管我认为他们不叫他们视图模型,只是轻量级的对象。您可以在其中放置更复杂的逻辑,但实际上最好最多调用其他地方处理的更复杂的逻辑。
另外,我认为这是关键,我的规则是,"ViewModel",不管你叫它什么,都不应该有任何不能由程序员编写的属性来查看线框。所以是var dateString : String而不是var date : NSDate。这是我在幻灯片中厚颜无耻的术语,"Modal Object属性转换器“。但这是一个很重要的问题:城堡需要能够提升吊桥,并在被围困时继续前进;当网络被切断(或者还不存在)时,一个视图需要充分发挥作用。在这么多场景中,您的时间要比视图能够做到的要容易得多。
就在几周前,我采用了这种方法,能够在大约4天内创造出多个复杂的屏幕,只能通过设计完成,最终会被来自网络的数据填充,但目前还没有任何模型或网络层。当数据层准备就绪时,我可以简单地编写一些创建方法init(with: Model)或更好的static func withModelforCase1(_ model: Model) -> ViewModel,并在创建方法中写入映射,然后当模型连接时,用这些创建方法替换static func debugCase1() -> ViewModel。随着模型的发展,编译器只会在这里抛出错误;随着视图的发展,调整ViewModel,编译器也会在这里和这里抛出错误。没有其他代码需要修改。
扩展在一开始看起来非常优雅,但是实际上在模型和视图之间创建了一个紧密的耦合。某种ViewModel方法是一个健壮的系统,满足了现代iOS应用程序和现代iOS应用程序开发的需要。
发布于 2017-06-23 10:59:08
MVVM的好处-- ViewModel是一个很好的地方,可以将您的验证逻辑用于用户输入、查看表示逻辑、网络请求。因此,ViewController文件变得不那么臃肿了。而且,ViewController组件与模型完全隔离。因此,在开发期间,一个开发人员可以处理屏幕的UI部分,而另一个开发人员可以独立和并发地处理屏幕的逻辑。在不干扰模型逻辑的情况下,很容易重新设计UI,因为它们都是完全孤立的。只要将适当的属性链接到ViewModel,就可以交换视图组件。这给了用户界面更多的实验自由。对于通用应用程序,iPad和iPhone ViewControllers都可以与相同的ViewModel交互。更容易测试。开发人员可以在没有视图的情况下为ViewModel和模型创建单元测试。
发布于 2017-06-23 08:56:35
ViewModel应该是一个与体系结构POV不同的实体,而不是代码放置POV。使用模型扩展的MVVM方法使模型知道得太多,违反了SRP,例如,如果模型具有某些日期属性,则视图模型通常用于使用当前区域设置对其进行格式化。如果模型是数据存储,则应该只包含相关的数据结构,而不包含任何方法。如果Model是一个服务(例如,网络客户端),它应该只包含相关的方法,且数据转换最少(例如,json到struct)。
另外,在我的实践中,我有时有多个VM到单个模型。例如,如果我有一个具有firstName、lastName和email属性的lastName模型,我可能需要fullName属性才能在表行中显示它(在UserCellViewModel中实现),但是当在详细视图中显示用户信息时(在UserDetailViewModel中实现),这三个属性都需要fullName属性。有了对模型的扩展,所有四个属性(在扩展中实现的fullName)都可以在所有上下文中访问。让使用ViewModel的控制器知道的越少越好(需要引用)。这可以在Objective中实现,在目标C中,扩展可以有自己的头/接口文件,但是您在Swift中没有这样做。
https://stackoverflow.com/questions/44716810
复制相似问题