V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
unt
V2EX  ›  程序员

从代码实例角度来分析 MVC 和 MVVM 框架

  •  
  •   unt · 2022-07-31 16:21:50 +08:00 via iPhone · 2796 次点击
    这是一个创建于 876 天前的主题,其中的信息可能已经有所发展或是发生改变。
    究竟什么是 MVC MVVM 架构,百度搜来的答案看腻了,同样的解释看了好几年,V 友们能否从代码实例角度来分析下,哪些代码属于 M ,哪些代码属于 V ,哪些代码属于 VM ,VM 和 C 的区别是什么
    14 条回复    2022-08-01 11:56:41 +08:00
    kissthekidlu
        1
    kissthekidlu  
       2022-07-31 16:31:10 +08:00 via Android   ❤️ 4
    v 的状态保存在 vm 中,v 属性直接绑定 vm 提供的数据和状态,行为绑定 command.保证 v 足够瘦。同时 v 和 vm 可测试
    ChrisFreeMan
        2
    ChrisFreeMan  
       2022-07-31 16:32:59 +08:00
    @kissthekidlu 言简意赅👍
    GeruzoniAnsasu
        3
    GeruzoniAnsasu  
       2022-07-31 16:40:01 +08:00   ❤️ 3
    M: class UserTable{};
    V: class Layout{UserTable ut;};
    C: for(UserTable t : data){ut->set(t);}

    VM: class UserView{User[] rows_; @property User[] rows(){return rows_;}; @rows.setter void rows(User[] &rs){rows_=rs; render();}}
    crayygy
        4
    crayygy  
       2022-07-31 17:07:31 +08:00 via Android
    MVVM 主要区别在数据绑定
    sillydaddy
        5
    sillydaddy  
       2022-07-31 17:35:53 +08:00
    这里插楼问一下:
    配合了 Redux 的 React ,是什么模式呢?
    我觉得,有一种理解可以是:它是 MVVM 的一个变形,因为它去掉了双向绑定中的,反向的一个绑定。
    其中 Redux 的 store 可以看作是 Model ,然后每个组件的 props ,是根据 store 经过 map 得来的,即 mapStateToProps (),为得是从 Model 层拿到渲染该组件所需的数据 ViewModel ,所以 props 可以看作是 ViewModel 。最后组件本身肯定是 View 了,而且 React 实现了 ViewModel->View 的单向绑定,只要 ViewModel 变化了,View 自动变化,但是反过来 View 到 ViewModel 并没有这个自动的过程,而且 View 层是直接修改的 Model 层的数据,不符合 MVVM 中,通过 ViewModel 来修改 Model 的过程。
    所以,呃,其实把 Redux+React 看作是 MVC 其实更合适,但是确实也可以从中看到 ViewModel 和 Model 之间关系的影子,也可以看到 React 自带的“数据绑定”的特点。。写不下去了。
    andyJado
        6
    andyJado  
       2022-07-31 20:21:50 +08:00
    你们前端我不知道, 写 swiftUI 这个熟:

    mvc: view 是 class, 堆分配.

    mvvm: view 是 struct, 栈分配.
    parrotdance
        7
    parrotdance  
       2022-07-31 21:32:26 +08:00
    借老东家老板, 也是前 QQ 开发的比喻来总结一句话, 希望能对楼主有所帮助:

    **VM 是"上帝之手", 替你包办了模型层 (M) 到视图层 (V) 的映射.**

    至于"上帝之手"的实现是和具体运行时紧密相关的. 网页端, Android, iOS 都有各自不同的实现, 但在"上帝之手"的帮助下你可以将大多数都精力集中在"数据如何变更"上, 而不太需要操心"数据如何影响视图"
    Building
        8
    Building  
       2022-07-31 22:20:46 +08:00
    最佳实例:
    M: html
    V: css
    C: js
    unt
        9
    unt  
    OP
       2022-07-31 23:59:14 +08:00 via iPhone
    @Building 太可怕了,不可能吧,绝不可能,你真乱讲不打草稿
    YYYeung
        10
    YYYeung  
       2022-08-01 00:07:49 +08:00
    从一开始,也许并没有 MVC ,只有一个文件,叫源文件,所有关于业务逻辑,UI 构建的代码都写在里面。

    后来,发现业务多起来了,这样子发展下去不行,维护起来太麻烦了;不过我发现,逻辑大致可以分成两部分:一个是数据模型,一个是 UI 视图,那么怎么把两个关联起来呢?中间需要一个类作协调,叫它控制器吧;
    好了,这个就叫做 MVC

    后来,发现 MVC 还是应付不了业务庞大起来的情况,数据模型太纤瘦,UI 视图还行,关键在于很多很多逻辑堆在了控制器里面,还是得从控制器抽点代码出来,那我们就把数据处理、转换部分的代码也抽出来吧;咦?好像 UI 层需要的数据也可以搬到里面;那么,这一层好像跟数据模型有关,也跟 UI 视图有关,那就叫它 view model 吧

    (我是写 iOS 的)咦?还有个 RxSwift 的东西,可以用这个东西把 view model 数据每一次变化通知到外面上。那我就可以在控制器中将 view model 与视图绑定起来,每一次数据发生变化,视图就可以更新了
    好了,这个就叫做 MVVM

    于是,从所有的代码写在一个文件中,演变成:viewModel 放乱七八糟的业务代码,只要把 UI 需要的数据发出去就可以了; View 就是 view ,不参杂任何业务处理的逻辑,就负责当花瓶;剩下的 controller ,原来乱七八糟的业务数据、处理都是写在里面,现在全外包出去了,重点就剩下绑定 viewModel 和 view ,说不定关于绑定的代码占了这个代码文件的一半以上

    其实核心就是一个,通过分拆代码使得日后维护工作简单快捷,可以早点下班。
    LinYa
        11
    LinYa  
       2022-08-01 08:52:50 +08:00
    看了上述的回答我还是没搞懂 VM 和 C 的区别。
    传统的控制器难道只负责业务逻辑,不负责数据绑定和交互事件的响应处理吗?
    wanguorui123
        12
    wanguorui123  
       2022-08-01 09:22:19 +08:00
    MV
    C:业务交互在控制器,通过出入参数实现业务,通过传入参数给视图渲染改变视图;
    VM:业务交互在视图模型,通过命令以及模型变化实现业务,通过视图模型属性改变视图;
    P:业务交互主要在事件处理器里以及自己定义的方法,通过各种事件以及事件参数变化实现业务,通过组件接口改变视图;
    cnuser002
        13
    cnuser002  
       2022-08-01 11:20:18 +08:00
    说到例子,我用过 Andorid Studio 开发安卓应用,那个挺符合 MVC 的。
    它的每个页面,由表里两部分组成。表面是视图 View ,作用是用 XML 定义页面中控件的位置、大小、样式。
    里面是 Activity ,这里面声明了页面中用到的控件的 Java 类实例。
    类实例和 View 中的控件,通过资源 id 关联到一起。

    然后它是怎么更新视图呢?是在 Activity 里面写触发。

    比如点击按钮,更新文本框。是在 Activity 中编写 onBtnClick 事件,这个事件中,调用 TextView 的类实例,改里面的 text 值,然后 TextView 类实例会触发更新,反馈到视图上。


    我曾经试过用 WPF 开发桌面应用,那是初次体验 MVVM 。感觉区别就是,像上面这个需求,onBtnClick 中,变成直接改 text ,由于 text 跟 TextView 控件有过绑定关系,所以 text 一改,TextView 显示的东西会改。并不需要我直接调用 TextView 中的 Function 或者 Prop 。
    ryougifujino
        14
    ryougifujino  
       2022-08-01 11:56:41 +08:00
    在前后端的视角下定义有所不同。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2984 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 00:36 · PVG 08:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.