聊聊MVC和模块化以及MVVM和组件化
原文链接 小寒的博客,带你理解更深的世界
面向对象,模块化和MVC
面向对象是指把写程序映射到现实生活,从而一来逻辑性更强,更容易写好代码,二来代码很贴切,通俗易懂,更被人理解,三来更加容易拓展和管理代码。
我们的代码设计应该有很多人,事物和场景,人是管理员,事物是数据库,场景就是业务。
面向对象
写代码就像在模拟现实的生活的处理公务,比如我们可以抽象出一些人帮我们来干活。
文章管理员,负责文章的CRUD,文章分类的CRUD
用户管理员,oauth passport和CRUD
邮件管理员,send email,邮件模版的CRUD
短信管理员,send SMS,短信模板的CRUD
消息管理员,send notification,站内和站外消息模版的CRUD
还有客户端管理员,交易管理员等等等等。。。
分布式开发中,还会借用一些其他服务器的管理员。
当然这里抽象出来多个管理员,还可以抽象出文章存储室,用户信息存储室这样的被管理的对象。
模块化
把代码按照功能和数据分成多个模块,文章模块,用户模块,邮件模块等等,一个模块可能对应多个管理员,比如文章模块里他可能有文章分类管理员,文章管理员,文章查看历史管理员。
模块可以理解为这个世界上有不同的行业,也可以理解为一个家里也有不同的分工,所以分模块可大可小,可以在大的模块里去区分子模块。总之模块是为了解决业务的耦合。就像分行业也是为了解决社会的耦合,但模块之间并不会区分的很彻底,就像各行各业总会有所关联,所以这也需要程序设计者们把握好度了。
模块之间的管理员之间是除了有分工之外,还有很大的合作。比如2C的应用里用户管理员总是需要忙个不停,因为他总要跑来跑去的帮助其他模块去识别用户
我们实现一个很复杂的功能,需求是这样的
某用户的博客发布之后需要其他的人登陆后才可以查看,查看的时候会给博客作者发个短信,告诉博主有人来看你的短信了,再给来看博客的人发个邮件说欢迎光临。
1. user = await UserManager.getByToken(req.header.token)
2. if (user) blog = await BlogManager.getById(req.params.blogId)
3. res.send(blog)
&& SMSManager.send(blog.author.phone, 'blog-be-read')
&& EmailManager.send(user.email, 'welcome')
MVC
这里呢UserManager BlogManager SMSManager EmailManager都是controller,理解为控制数据。
res.send(blog) 中的blog是view,可以理解为要呈现给前端的东西。
这些管理圆管理的模版和数据库则属于model,可以理解为原始的数据。
mvc是应对复杂业务场景的后台最常见的设计模式,会把程序抽象成三层,就像在面向对象里说的那样,一个程序应该有人,事物,业务,其实也可以理解为人就是controller,事物是model,业务是view。对于web后端来说view经常会是web前端。
前端的MVC
类比于后端的MVC
在前端
M指的是后台给的数据,即原始数据
V仍然是要呈现的数据,但是是呈现给用户的界面
C值得是处理后台的数据和view层的交互逻辑
具体实现呢
// model
model = res.data
// controller
view.date = Formater.formatTime(model.date)
view.author = Formater.formatUserName(model.author)
view.blog = BlogController.beautify(model.blog)
// view
document.write(view.author)
document.write(view.date)
document.write(view.blog)
document.write相对于res.send是一样的
前端也会有一些工作人员比如 Formater, BlogController也是控制数据的
是不是和后端很像呀
不同的是前端的view很复杂model很简单,后端的model很复杂view很简单。
前端对MVC的不足
前端的view可能只是在展示数据,这样的网站很适合用MVC,比如管理系统,一个页面一个table的那种。
但也很可能非常复杂,比如在2C的程序中页面可能要肩负各种复杂的操作,操作太琐碎,controller就会变得很臃肿。比如说这个网站里的音乐播放器,要有
上一首,下一首,随机播放,单曲循环,音量,显示列表,显示歌词,关闭歌词,显示列表,选择歌曲,关闭列表,暂停,继续,快进,快退,更新播放时间等等等等的功能。。。这个时候功能这些功能要全部写在controller里同时还要发起请求更新数据,监听时间变化,controller就很复杂。
我们通常都是请求一次后台,然后塞一个列表进去,然后用户切换音乐只是在本地内存里读取数据。
这个时候就会有问题
1. 前端的复杂的操作不像后块化那样可以解耦,前端页面之间,组件之间的耦合应该如何处理
2. 前端的复杂的操作太多了,controller要处理事件还要处理请求,如何减轻维护controller的成本
3. 单页面应用中需要在前端维护一份数据,这份数据只是临时的,不可以放在后端的model里应该放在哪
同时我们也会发现,复杂的业务场景里view和controller的事件处理部分逻辑关系相当密切,所以开发者经常会把controller和view封装在一起,这个时候就出现了组件。
而开发者会在前端暂存一封数据,因为浏览器不用经常刷新了,不需要经常发起请求,因此出现了vm,意指view model。和model的区别就是他是针对view的model。
就这样出现了mvvm和组件化
组件化和MVVM
MVVM
归根结底的说MVC不适合前端的一些业务场景就是因为后端V会相对简单,重点在于解决controller和model的关系。前端的V很复杂,重点在于解决view和controller的问题。
在MVVM中
M不变,可以认为他是数据来源,M很简单,但数据往往不是view需要的。
V是UI和用户输入。面对复杂的用户操作而且要迅速给予反馈,操作和展示往往是同时存在的,比如一个表单就肯定会有表达数据和接受输入两种属性。这就是组件,组件同时具有两种能力,接受输入获取反馈也是MVVM里的第二个V。
VM是在单页应用里出现的一种概念,在单页面的应用里数据在用户不刷新的状态下可以一直暂存在浏览器的内存里,因而把数据请求到本地之后就缓存在客户端的内存里,可以大幅度的复用数据,同时也需要有一层类似于数据库的VM是专门为V提供的model,所以他必须给V更加准确和舒适的数据,以及获取数据和修改数据的方式。同时VM也要减少V里复杂的controller里的api冗余,避免过于繁重的controller,所以和VM也需要负责发起请求。
最后结论就是。
M是response data
V是view + user action controller
VM是store + request controller
这样写的好处有
1. view中加入controller可以增强组件化,view和controller更加密切,可以专注的的表达UI和交互逻辑,把前端的任务大幅度专注在用户体验和UI构建上。
2. 分离model和view之间的直接联系,把和后端交流的任务分配给了view model,确保view拿到的数据更加优雅和易用。
3. 前端暂留一份数据层,供自己的UI使用。同时也把请求数据,处理后台数据的任务给了vm。大幅度减少了controller里的代码。还能起到复用请求和处理数据代码的好处。
组件化
组件化也是面向对象的一种表现。但是组件化和模块化开发在感觉上会又很大的区别。
组件是一种有着强大功能的 "dom" 元素。
组件的任务是用户体验和UI构建。
比如这个博客网站就是由 1. 留言表单 2. 逐个出现的动画组件,3. 音乐播放器,4. 音乐背景墙和歌词组件,5. 博客导航菜单组件 6. 歌单组件 7 歌曲组件 8 导航组件 9 底部组件 10 博客内容 11 博客列表 构成。
我罗列了以下,意思就是说这么大的一个网站其实可以只是这么几个组件而已,这就是组件化的好处。专注构建UI和提升用户体验。
前端组件分类
从bootstrap开始组件分类就已经开始了,通常我们会认为有
antd分为通用,布局,导航,数据录入,数据展示,反馈和其他
这个分类很难以辩驳,个人觉得比较合理,但是这种分类的依据很难说的出来。因为上学的时候,书本里的分类前都会说按照XXX分类可以分为。但是antd这个分类方法就不容易感知到了。
比如通用和数据录入显然并不是一种分类方法。通用是表达组件的使用范围广度,数据录入是按照功能划分的
再比如数据展示和反馈很可能差不多,只是反馈不是直接的数据展示。
但细想以下,这种分类确实也表现出了各个类别里组件的特点。总之分类只是便于理解。因为分不开呀。
我通常会把组件的作用分为以下三种
1. 用于数据展示的
2. 用于接受用户操作的
3. 辅助和增强功能
严谨的说这个是分类组件的功能,而不是给组件分类。而几乎大多数组件都很容易就具有1 2 两种属性。但能看出他们更倾向于那种。
比如
Collapse就是辅助和功能性的,我们市面上见到的都是CollapsePanel这个组件,而Panel是展示数据的组件。
Table就是数据展示的,被我们拓展封装之后呢,我们用到的Table很可能是TableWithPagination,这就让Table就可以接受用户输入了。但Table是更倾向于展示数据的组件
Button是更倾向于用户操作的组件,因为他很能展示文字。
所以可以发现我们用到的组件大多都是有不同的属性的,就像问道里的人物角色一样,三敏一体一力 什么什么的。就是敏捷型的角色。
网站本身是倾向于数据展示的一种应用。因此有些也不好归类为更倾向于某种功能,篇幅有限,总之这个话题想要得到一个比较妥善的答案可以讨论几千字吧。
React不是框架
React是一个构造可组合式用户界面的库,它鼓励创建可重用的UI组件去显示会随着时间而改变的数据。
很多人写react的出发点是错的,和angular,vue出发点并不相同。facebook发明react的原因是在富交互时代的web开发中,如何更好的组织UI是一个很棘手的问题,而通过组件的方式可以很好的解决了这个问题,所以发明了react。
所以说白了react只是一个解决UI问题的工具库而已,使用这个库我们可以很方便的构建一些复杂的交互和样式,并把网站抽象成一个个组件,然后简化web UI的开发,而配合这个库使用解决其他问题的比如react-redux,
react-router等等则是解决web开发的除了UI以外的数据管理和路由等问题的。
如果不能抽象UI,那么用react可能对你来说并不合适甚至很可能是一种累赘,用vue或者ng可以大幅度减少代码量
参考链接:
聊聊MVC和模块化以及MVVM和组件化的更多相关文章
- iOS组件化开发· 什么是组件化
越来越多公司,开始了组件化,你还要等到什么时候...... 说到开发模式,我们最熟知的开发模式 MVC 或者最近比较热门的MVVM.但是我今天说的组件化的开发,其实MVC不是一类的.它其实是····· ...
- iOS组件化开发入门 —— 提交自己的私有库
前言:本人也是初次接触组件化开发,感觉现有的资料太繁杂,就简单整理了一下,在此跟大家分享一些入手的经验,主要就是描述cocoapods的私有库封装和提交.组件化开发是个大的议题,涉及到架构思路.设计模 ...
- vue - Vue组件化编程
今天是对vue组件化的一个理解,最主要的单文件组件,然后就可以脚手架的学习了,本来昨晚就该上传的,但是用的那个上传博客园的Python脚本不行了,换了一个新的. 组件化让我越来越感觉到框架的力量了 一 ...
- 【移动前端开发实践】从无到有(统计、请求、MVC、模块化)H5开发须知
前言 不知不觉来百度已有半年之久,这半年是996的半年,是孤军奋战的半年,是跌跌撞撞的半年,一个字:真的是累死人啦! 我所进入的团队相当于公司内部创业团队,人员基本全部是新招的,最初开发时连数据库都没 ...
- 转:界面之下:还原真实的 MVC、MVP、MVVM 模式
前言 做客户端开发.前端开发对MVC.MVP.MVVM这些名词不了解也应该大致听过,都是为了解决图形界面应用程序复杂性管理问题而产生的应用架构模式.网上很多文章关于这方面的讨论比较杂乱,各种MV*模式 ...
- [转]MVC、MVP、MVVM
界面之下:还原真实的 MVC.MVP.MVVM 模式 [日期:2015-10-28] 来源:github.com/livoras 作者:戴嘉华 [字体:大 中 小] 前言 做客户端开发.前端开发 ...
- MVC,MVP 和 MVVM 模式如何选择?
转摘:http://www.linuxidc.com/Linux/2015-10/124622.htm 前言 做客户端开发.前端开发对MVC.MVP.MVVM这些名词不了解也应该大致听过,都是为了解决 ...
- MVC、MVP、MVVM 模式
一.前言 做客户端开发.前端开发对MVC.MVP.MVVM这些名词不了解也应该大致听过,都是为了解决图形界面应用程序复杂性管理问题而产生的应用架构模式.网上很多文章关于这方面的讨论比较杂乱,各种MV* ...
- mvc与mvp与mvvm
==MVC,MVP和MVVM都是常见的软件架构设计模式,它通过分离关注点来改进代码的组织方式== MVC.MVP和MVVM的相同点和不同点 不同部分是C(Controller).P(Presenter ...
随机推荐
- express 创建项目
express 创建项目: 1.熟悉express命令 2.创建模板 3.安装组件
- jquery网页定位导航特效
<!DOCTYPE html> <html lang="en"> <head> <script src="http://code ...
- Spring Boot 整合 Druid && 配置数据源监控
1. 导入 Druid 包 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid& ...
- 跳一跳外挂的python实现--OpenCV步步精深
去我的个人网站看看吧 http://opencvblog.com/跳一跳外挂-python实现/ 都在这里啦
- ATC/TC/CF
10.25 去打 CF,然后被 CF 打了. CF EDU 75 A. Broken Keyboard 精神恍惚,WA 了一发. B. Binary Palindromes 比赛中的憨憨做法,考虑一个 ...
- 【POJ】1426 Find The Multiple
题目链接:http://poj.org/problem?id=1426 题意:给定一个正整数n,找一个比n大且能只由01构成的且能够被n整除的数. 题解:这个就是在后面添0和添1小心试探.一定要是添0 ...
- 【转载】C# 开源库大全非常好
原文地址:http://m.blog.csdn.net/woddle/article/details/37311877 C#开源大全 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMuk ...
- JS事件 内容选中事件(onselect)选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行。
内容选中事件(onselect) 选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行. 如下代码,当选中用户文本框内的文字时,触发onselect 事件, ...
- 7.spark运行模式
sparkbin目录下 ./pyspark --help http://spark.apache.org/docs/latest/submitting-applications.h ...
- ac与ap同步分析
1 ApStatusRequest : ap把自己的状态发过来做请求 就相当于自我介绍 网关上抓包 : tcpdump -ni br-lan tcp port 8090 -Avv / -w po ...