谈对象 MVC 和 多端
什么是对象?
我是单身狗,我没有对象;我是C程序猿,我没有对象;我是程序猿,我只会new一个对象。
言归正传,想想从一个电商网站上买一个东西,“进入首页,搜索商品,选型购买,登录下单,支付完成”,这里面有多少个对象。在我的理解中,对象是一个物,无论是一个真实的物还是一个虚拟的物,但不会是一个动作。比如“登录”是一个动作而不是一个物,所以“登录”不应该是一个对象(类定义),而应该是用户对象里面的一个方法。所以上面那一句的流程中,明显涉及的对象有:商品、用户、购物车、订单,隐含的对象有:页面控制器。
但是,随着业务的复杂,有些动作又会衍生出一个对象,比如当“登录”接入多种第三方OAuth登录时,就会多出一个“OAuth”控制器;“搜索”功能需要比较强大时,必然要加入一个“搜索引擎”控制器。有些对象可能又需要从中拆分出对象,比如“商品”对象可能会需要拆分出“属性参数”对象等等。这个问题似乎很复杂,但也并非无迹可循,我的经验是:从最直接的名词开始规划类和对象,动词和名词内部的名词根据发展需要再进行扩充。
对象规划与职能划分
什么叫职能划分,就是一个对象做它自身的事情。说起来似乎是一个很基本的原则,但是很遗憾,我看过的不少开源PHP项目都没有这个理念。在谈这个问题之前,我想先谈谈嵌入式C语言中的对象。
有研究过C语言和单片机的会知道,C语言里面一个C文件加上相对应的H文件就相当于一个类,是不是感觉和JAVA很像,一个文件就是一个类。当然这个不仅限于这两三门语言,应该是绝大部分语言所共同遵循的规则。在单片机程序开发中,一个硬件模块应该对应一个C和H文件,如一个温度传感器就应该有一个类似于 Temp.c和Temp.h的文件,里面的应该有的方法就是 初始化传感器 和 读取温度。在这个C文件(类)里面,所拥有的函数应该只和这个模块的功能(温度)相关,你可以添加类似于以字符串、符点数、整数返回等等的读取温度方法,但不能加上例如 “符点数转字符串” , “显示温度” 这样的方法。为什么呢?“符点数转字符串”虽然是这里面的一个必须方法,但它是一个通用方法,大部分其它地方都可能会用到,如果是自己实现的话那应该放到一个公共函数文件(如 pubfunc.c)里面去。当然C库里面已经有实现好了的就不要重复造轮子了。“显示温度”看似是一个跟温度非常相关的功能,但是它跟温度传感器并没有关联。你可能会用黑白屏显示、也可能会用彩色屏显示、也可能会用语音播报,这种情况就不能把显示温度放在Temp.c里面,而是应该在业务C文件里把数据读出来运算处理,最后把数据传到对应的显示设备的C文件中去展示。
说到这里,大家可能已经隐约感觉到分层这个理念了,分层稍后再提,先看回网站中应该怎么对象划分。PHP中有函数和方法两种不同的function,函数是应该是公共的,就像前面提到的pubfunc.c一样,还有一些类也是公共的,比如分页类、加密类等,这些文件里面不应该与项目的业务逻辑有耦合关系,应该拿出来给另外一个项目也是通用的。而另一方面的项目功能模块呢,应该是职责明确的,比如用户控制器就应该有读写用户信息、登录注册等等,而不应该有订单数量这种东西。
为什么要MVC和怎么MVC
MVC即是模型-视图-控制器的意思,但实践中,我发现这种统一的MVC说法并不能适应到程序编程的各行各业。毕竟编程有 嵌入式开发、电脑软件开发、手机APP开发、网站开发、游戏开发等等,对应不同的场景应该会有略有不同的具体实现。在此我仅对我自己所使用的网站MVC模式作出介绍,有不当之处恳请提出。
如下图所示,浏览器发出的请求分成两大类,一类是页面请求(红色箭头+蓝色箭头),一类是AJAX纯数据请求(绿色箭头+蓝色箭头),服务器上的代码资源也分为两类,一个是PHP框架的(青底黑框表示),一个是自主开发的(白底蓝框表示)。
1、浏览器发出到服务器,框架通过URL路由分发请求到控制器里,当中可能会做了URL优化什么的。
2、页面请求(根据URL判断)全部转发到页面控制器中(暂时只有IndexController一个),然后调用逻辑控制器;AJAX请求则直接分发到对应的逻辑控制器,逻辑控制器通过一定的策略判断需要AJAX返回还是函数return(如可选参数)。
3、比较简单的逻辑直接在逻辑控制器中处理,直接使用“表模型”访问数据库,我这里说的“表模型”是指没有定义Model类,但是使用对象的方式去操作数据库,通常以表为操作单位,相当于ThinkPHP框架中的M()方法。
4、 对于比较复杂的逻辑,可以进一步封装在一个Model模型中,Thinkphp中称为“虚拟模型”,是指这个模型不一定会有对应的数据表,当然也可能有对 应的表。对于到达何种复杂度就封装到Model中,我经验不足暂无法下定论,因为现在为止我的项目还没有使用“虚拟模型”,也就是说我把MVC三层中把C 层拆分出了两层,而M层至今留空。至于为何这样做,稍后再分析。
5、到这里已经到达了数据库了,取回数据顺着蓝色箭头反方向返回,数据再次 来到了逻辑控制器。如果是AJAX数据请求,则直接echo输出数据或者操作结果,或者用TP内置的ajaxReturn()方法,两者有数据 header的区别,至此AJAX请求就处理结束了,剩下就交给前端JS去处理了。如果是页面请求,则把数据返回给页面控制器,注意这里是函数 return而不是打印输出。
6、页面控制器收集好各个调用到的逻辑控制器返回的数据,利用框架内置的模板引擎或者Smarty引擎,将数据赋值到页面文件中,最后渲染页面输出。
多用户端(模块)和继承
前文再续就书接上一回,上回讲到 我的项目中M层一直为空的。为什么呢?网站这一种程序,通常都会有多端的情况,就是会有 PC端、WAP端、管理端、APP端等等,这个在Thinkphp3.2中称为“模块”。我目前项目中就有 Home(PC端)、Mobile(移动端)、Admin(管理端) 三大模块了。那三大模块就写三份程序吗?显然不应该这样,因为它们之间绝大部分的逻辑是相同的,应该使用继承,而我们的项目中 Home 模块功能最基础、Mobile次之,Admin则是权限最高的模块,大部分写/修改操作只允许在Admin模块中有。所以我项目现有的结构是 Home模块中的类是基类,Mobile继承Home,Admin也继承Home,以后如果感觉有必要的话,也可能会使用一个Common模块,Home、Mobile、Admin都继承于Common。
然后这样的关键就来了,既然有那么多的模块,那么多的类,那么多的模型,如果要新增一个功能那应该写在哪里呢?我们的决定是,很长一段时间内都暂不使用Model类,避免大量继承过来并没有新增功能的“空Model”而导致找查找代码浪费时间;对于新增的功能,如果是一类全新的功能,比如折扣功能,则在几个模块中都新建一个逻辑控制器文件,继承方式同前文所提。新的方法如果可能在PC和移动端都用到的话,就写在Home的控制器里面,如果只有移动端用到的话就写在Mobile的控制器里面,如果是后台管理方面的功能则写在Admin的控制器里面。
实践证明,这样一个决策是可行的,直到现在Mobile模块里面还有半数的控制器是空的(即与PC一致没有新增功能),如果是加上了Model层的话,目测各个类里面的方法会写得很分散,各种继承错综复杂,那些方法要到各个模块下的控制器、模型各种到处找。
我是PHP程序猿,我只有一半对象(PHP的吉祥物是一只象,即半对象,而且PHP可以用或完全不用对象来写程序)
谈对象 MVC 和 多端的更多相关文章
- SignalR Self Host+MVC等多端消息推送服务(3)
一.概述 最近项目确实太忙,而且身体也有点不舒服,慢性咽炎犯了,昨晚睡觉时喘不过气来,一直没休息好,也没什么时间写博客,今天朋友问我什么时候能出web端的消息发送的文章时,我还在忙着改项目的事,趁着中 ...
- [备忘]Asp.net MVC 将服务端Model传递的对象转为客户端javascript对象
<script type="text/javascript"> var jsObject = @Html.Raw(Json.Encode(Model.Objects)) ...
- 浅谈Spring MVC知识
关于MVC框架,我相信大家都不陌生,都会说也就是模型-视图-控制器这三层的框架结构,如果你参加面试的时候考官会问:“MVC框架是什么?你说一说.”其实我们都知道这个问题还需要问的,只要你是一个开发人员 ...
- 浅谈对MVC的理解
1.MVC设计模式理解 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界 ...
- ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制
我曾经试过使用JSAjaxFileUploader插件来把文件.照片以异步的方式上传,就像"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01- ...
- 浅谈.net MVC
大学毕业对MVC的概念还不是很清晰,总觉得MVC是和三层一样的,是同一级别的架构.其实不然,三层架构是:BLL(业务逻辑层),DAL(数据库访问层),UI(页面显示层),而MVC仅仅是属于三层架构UI ...
- 关于JavaScript对象,你所不知道的事(一)- 先谈对象
这篇博文的主要目的是为了填坑,很久之前我发表了一篇名为关于JavaScript对象中的一切(一) - 对象属性的文章,想要谈一谈JavaScript对象,可那时只是贴了一张关于这个主题的思维导图,今天 ...
- 我要谈对象之——JavaScript面向对象(1)
任何语言里都有面向对象,除了个别的.今天,我要说的是javascript中面向对象. 什么是面向对象? 计算机中的一切算法和逻辑都是源于生活中的,对象,这个抽象的概念并不是男同胞理解的妹子哈,对象,无 ...
- 扯谈spring mvc之WebApplicationContext的继承关系
spring mvc里的root/child WebApplicationContext的继承关系 在传统的spring mvc程序里会有两个WebApplicationContext,一个是pare ...
随机推荐
- Git从零教你入门(4):Git服务之 gogs部署安装
Git从零入门系列4: 先看上一篇文章: http://www.51testing.com/index.php?uid-497177-action-viewspace-itemid-3706817 今 ...
- cocos2d-x 3.10 屏幕适配问题
cocos2d-x 的屏幕适配问题困扰了我很久,差不多有一个星期吧.通过亲身实践才解决了问题,分享一下解决办法,供大家借鉴学习. 其实解决办法很简单,把下面代码注释掉就好了 // if (frameS ...
- IE6-11使用location.href提交时的链接复制到firefox或chrome时出现乱码
这是在开发国际机票查询页时碰到的一个问题,测试工程师在IE里执行查询操作,然后把查询的url赋值到firefox的地址栏,firefox打开后就变成乱码了. 1. IE浏览器,选择出发地,出发日期等后 ...
- 002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)
一.大致流程: 将ICMP头和时间数据设置好后,通过创建好的原始套接字socket发出去.目的主机计算效验和后会将数据原样返回,用当前时间和返回的数据结算时间差,计算出rtt. 二.数据结构: ICM ...
- 配置安装DVWA
本文地址:http://www.cnblogs.com/go2bed/p/4162313.html —————————————————— 什么是DVWA? Damn Vulnerable Web Ap ...
- TFS 2013 生成(构建)历史记录保持策略(Retention Policy)
TFS服务器通过自动构建,实现软件生成和发布的自动化过程,这一直是TFS系统中非常重要的一个功能模块.近年来发布的TFS版本,都在自动化构建方面大幅增强了相应的功能.在这篇博客里我主要总结TFS 20 ...
- 【转】 svn 错误 以及 中文翻译
直接Ctrl+F 搜索你要找的错 # # Simplified Chinese translation for subversion package # This file is distribute ...
- C#基础---IComparable用法,实现List<T>.sort()排序
List<T>.sort()可以实现对T的排序,比如List<int>.sort()执行后集合会按照int从小到大排序.如果T是一个自定义的Object,可是我们想按照自己的方 ...
- [麦先生]SEO--相关优化【基础】
收录的一个重要原则:离首页的远近.离首页太远,不容易被收录.内页必须距离首页3-4次点击之内. 原因:1.对于一个网站来说,搜索引擎经常来的地方是首页,因为很多外部链接链向的是首页如友情链接.做的外链 ...
- RCC BUCK变压器设计
RCC电路工作于临界模式,不是固定工作频率,其设计遵从BUCK原理.Buck电路在最高输入电压时为电感最恶劣工作条件: 以下图为例: 1.首先设定如下参数:输入电压Vin,输出电压Iout,工作频率f ...