文章摘要
MVC模式最初由Smalltalk定义,包含模型、视图和控制器三个对象,分别负责应用逻辑、界面展示和用户输入响应。然而,多年来该模式被滥用,尤其是苹果在2003年的定义中模糊了控制器的角色,导致其可复用性降低。尽管苹果后来区分了传统Smalltalk MVC与Cocoa版本,但Cocoa的定义仍保留了控制器作为视图与模型中介的角色,未能完全解决早期问题。
文章总结
MVC模式为何变得如此混乱?
MVC(Model-View-Controller)模式最初在Smalltalk中被定义为由三种对象组成:模型(Model)是应用对象,视图(View)是其在屏幕上的呈现,控制器(Controller)定义了用户界面如何响应用户输入。然而,随着时间的推移,这一概念被滥用和误解。
2003年,作者曾批评苹果公司对MVC的定义,当时苹果认为控制器是应用中最不可重用的对象,但这一观点并不正确。尽管苹果后来对其定义进行了修正,区分了传统的Smalltalk MVC和Cocoa版本的MVC,但Cocoa版本的定义仍然与之前相似,强调控制器作为视图和模型之间的中介。
在iOS应用开发中,控制器(尤其是视图控制器)仍然是最不可重用的组件之一。MVC的核心结构是模型、视图和控制器之间的直接或间接关联。模型通过通知间接与视图和控制器交互,而视图和控制器则绑定到模型上。然而,在实际开发中,控制器和视图的功能常常被紧密耦合在一起,形成一个“控件”或“小部件”,导致代码混乱。
正确理解MVC的关键在于明确模型的本质。模型是一个可以被观察的对象,视图通过观察模型的变化来更新自身。例如,一个简单的可观察布尔值模型可以与复选框视图绑定,当控制器请求改变值时,模型更新并通知视图。模型并不关心与其绑定的UI是什么,甚至可以有多个UI绑定到同一个模型实例上。
与大多数UI框架不同,MVC中视图的状态始终反映模型的当前状态,而不是通过查询视图来获取状态。这种设计避免了将两个模型绑定在一起的问题,使得系统更具扩展性。
MVC模式之所以被误解,部分原因在于在像Pascal或C这样的语言中,实现一个简单的可观察布尔值模型较为复杂,涉及到对象所有权、生命周期和绑定表达式等问题。此外,如果假设UI与模型之间存在一对一的映射关系,也会导致系统效率低下。
为了支持更复杂的视图,通知可能需要指定模型的哪些部分发生了变化以及如何变化。例如,“序列中的第58张图片被移除”。一个完整的模型应该能够高效地支持任何类型的视图。
MVC模式还是一种复合模式,视图可能包含状态,这些状态本身也是可观察的对象,形成了视图的模型。识别系统中的模型非常重要,通常我们能够识别主要模型,但往往忽略了完整模型的识别,导致模型分散在代码中,增加了处理的难度。
一个常被忽视的模型是函数参数的模型。在应用中,命令、按钮、手势或菜单项通常绑定到函数上,这些函数通常带有参数,这些参数需要通过UI的其他部分构建。例如,删除选中图片的按钮需要将当前选中项作为参数传递给删除命令。为了创建选择项的UI,必须为函数参数创建一个模型,并在模型中观察前置条件,以便在视图中禁用或隐藏按钮,并在控制器中阻止用户点击按钮执行命令。
总之,MVC模式的混乱源于对其核心概念的误解和滥用,正确理解模型、视图和控制器之间的关系是避免这一问题的关键。
评论总结
评论内容主要围绕MVC(Model-View-Controller)设计模式的定义、应用和争议展开,以下是主要观点和论据的总结:
1. MVC定义的模糊性
- 观点:MVC的定义在不同场景下差异较大,导致理解和应用上的混乱。
- 论据:
- "I think nearly every definition of MVC I've read has been different." (评论1)
- "the original/popular definitions were so incredibly abstract and disconnected from real life usage that they ended up being whatever the person implementing it wanted it to be." (评论4)
2. MVC的滥用与误解
- 观点:MVC在快速应用开发(RAD)框架中被滥用,导致其核心价值被忽视。
- 论据:
- "The reason MVC got so abused was because of RAD frameworks: rapid application development." (评论6)
- "MVC is a fake that lasted for decades." (评论14)
3. MVC的测试性与模型的重要性
- 观点:纯模型(Model)的测试性是其优势,但测试在应用开发中常被低估。
- 论据:
- "A major advantage of pure models is testability." (评论2)
- "If automated testing were seen as a priority, this would be a no-brainer for any serious app." (评论2)
4. MVC的原始设计与现代应用的脱节
- 观点:MVC的原始设计(如Smalltalk中的实现)与现代应用中的实现存在较大差异。
- 论据:
- "Smalltalk's OOP is nothing like what existed either before or after." (评论4)
- "I used to say things like this. M and V were always pretty unambiguous, but 'controller' was kind of like 'Christianity'." (评论10)
5. MVC的实践问题
- 观点:在实际应用中,MVC的分离往往显得人为且不自然,尤其是View和Controller的耦合。
- 论据:
- "Any implementation of MVC I've seen the V and the C are so tightly coupled the separation seemed artificial." (评论5)
- "If you've got strictly one-to-one-to-one matches for each model, view, and controller, then you're just setting your design budget on fire." (评论8)
6. MVC的替代方案与未来
- 观点:随着技术的发展,MVC可能不再是唯一或最佳的选择,尤其是在现代前端框架中。
- 论据:
- "Nowadays, with vibe coding, there is no need to use obtuse design patterns for the sake of RAD." (评论6)
- "SwiftUI was designed to be more flexible, and can employ other patterns." (评论21)
7. MVC的复杂性与实际应用中的挑战
- 观点:MVC在理论中简单,但在实际应用中可能变得复杂,尤其是在处理复杂视图和状态管理时。
- 论据:
- "The thing is that they are quite simple in theory but in practice, programming them from scratch can be much more difficult." (评论18)
- "At this point you need a state machine to track the state and where the user is currently at." (评论18)
8. MVC的模型与控制器争议
- 观点:模型的定义相对明确,但控制器的角色和定义常常引发争议。
- 论据:
- "Everyone knows what model is. Almost noone knows what is controller." (评论15)
- "Controllers are a bit of a catch-all for stuff that didn't fit anywhere else." (评论16)
9. MVC的原始设计与现代框架的对比
- 观点:MVC的原始设计强调模型与视图的分离,而现代框架(如React)则通过状态管理工具(如Redux)重新诠释了MVC。
- 论据:
- "So like in React, you'd have your Redux store as the Model, React components (with useState etc) as the View, and then your Controller is the reducer." (评论7)
- "IIRC, that was one of the problems that React was trying to solve with 'MVC', except it turns out that actual MVC never had those problems in the first place." (评论16)
10. MVC的模型定义争议
- 观点:模型不应被简单地视为单一对象,而应是多个协作对象的集合。
- 论据:
- "This perpetuates the myth that a model is an object. One object." (评论9)
- "Instead a model is one or more collaborating objects." (评论9)
总结:
MVC作为一种经典的设计模式,其定义和应用在不同场景下存在较大差异,导致开发者对其理解和实践存在争议。尽管MVC在测试性和分离关注点方面有其优势,但在现代应用开发中,其原始设计与实际需求之间的脱节、控制器的模糊性以及复杂视图管理的挑战,使得MVC不再是唯一或最佳的选择。随着技术的发展,新的架构模式和框架(如React、SwiftUI)正在重新定义应用开发的最佳实践。