当pageIndex遇上pageNo
作者发现,本文被多个博客和网站转发。赠人玫瑰,手有余香!
本文版权归作者和博客园共有,欢迎转载,转载请注明出处: https://www.cnblogs.com/buguge
我们的项目程序里,由于赶项目进度,同时,大家缺乏相应的沟通,在服务层提供的接口里,涉及到分页查询的,有如下三种情形:
l List<OrderInfo> GetOrderList(OrderQueryModel condition, int pageIndex, int pageSize);
l List<OrderInfo> GetOrderList(OrderQueryModel condition, int pageNo, int pageSize);
l List<OrderInfo> GetOrderList(OrderQueryModel condition, PageMode pagedInfo);
对于以上的接口声明,同时涉及到了pageIndex和pageNo,加上缺乏必要的注释,前端开发组人员的调用方式,尤其是获取第一页数据时,就有些犯迷糊了,有的给的是0,有的给的是1。开发经理在review大家的交付成果时,显然就出现bug了。 于是,倡导统一就显得很迫切了,但是由于项目比较庞大,怕修改会带来新的麻烦。
架构师观点:从使用习惯上来看,pageIndex是从0开始的,index嘛;而pageNo表示计数,所以从1开始就比较容易理解了。
技术总监:不管是叫什么名了,就约束前端调用方从1开始传递这个参数。(技术总监的英语水平用一个名牌形容就是TCL)。
我觉得这种重构是值得尽快来做,越往后拖的话可能就越糟糕,就执意坚持。 最后,和开发经理花了2个小时,并做了一些检查,最终修复成如下方案:
分页查询使用统一模型PageModel,其中,页码属性使用PageIndex,调用方从0开始传参。即第一页的话pageIndex=0,第二页pageIndex=1,et cetera.
毕竟这是团队项目,底层框架、技术预研、服务层逻辑、前端UI,大家有不同的分工。我想,即使是完全交给某一个人来做,迟早他也会乱的。因此,尤其是team leader,应该尽早在做code review时发现这些问题,并统一开发规范。这就完了吗?没有,接下来是…………………………………..………………………………….…………………………………..………………………………….………………………………..………………………………….………………………………..………………………………….………………………………..………………………………….………………………………..………………………………….……………………………..………………………………….………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….………………………………..…………………………………. …………………………………..………………………………….…………………………………..…………………………………………………………………..…………………………………. …………………………………..………………………………….…………………………………..…………………………………………………………………..…………………………………. …………………………………..………………………………….…………………………………..…………………………………………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….…………………………………..………………………………….…………………………………..…………………………………. …………………………………..………………………………….监控大家的执行情况。
跑题了,接着聊一点规范吧。在你的开发组的项目里,
l 就商品/产品的命名上,是否同时存在product和goods甚至good? 就手机号的命名上,是否同时存在mobile和phone和telephone甚至mphone甚至tel?
l 是否存在一些全局变量(在使用时才声明变量,这是个好习惯,全局作用域极易因使用不当而带来潜在风险)
l 调用别人接口得到引用类型或集合后,是不是不判断为null(有时还需判断其Count>0)就直接使用?(不要轻信别人的代码,即使他确信不会返回null) 同样,是否也对接收到的参数做类似的判断?
l ……
继续,我的一点实践总结:
l 对于List对象的命名。通常以-List结尾,比如productList、orderList。另一种方式,对于名词,可以以其复数形式来命名。如products、orders,而对于idList,则最好不用ids。
l 我们目前的项目是一个B2B+B2C模式的电商交易系统,订单表名自然是喜闻乐见的orders。这个表同时存放这2种模式的交易数据,对于零售来说是零售订单,对于商家交易来说是采购单。Orders表与会员(普通用户和商家)的ER见下图。对于交易涉及到的双方,orders表里有2个字段CustomerId和ShopId。随着业务逻辑梳理、服务层逻辑代码的编写、客户端调用、需求微调所致迭代等工作的不断进行,发现买家卖家登录后对这2个属性赋值查看自己订单列表时,存在诸多不便,尤其是理解层面。目前,项目在逐步将这2个属性改为BuyerId和SellerId(同样的CustomerName改为BuyerName,ShopName改为SellerName)。
l 在我们项目里,商城一些推荐栏比如推荐商品,这个功能是由运营人员通过后台来设置的,这个列表的显示需要有排序,这时在领域模型里就要有这么一个显示序号的属性,我们起初命名成了ShowOrder,后来改成了DisplayNo,为了避免让大家联想到订单。
我很赞同我们项目组架构师的一句话:“架构要考虑成本和效率”。他在面试求职者时曾提问:“如何做到你的接口不需要用户借助说明文档就能理解?” 值得我们思考。
真的是有最佳实践的,
如webservice的wsdl。
再如public void CreateCache(int cacheSize)
传入的数据是bytes, KB, MB 还是GB?
改成public void CreateCache(int cacheSize_mb)
一目了然,并且会减少调用者传入错误数据的可能。
再让我们看看微软底层对一些参数的命名:
public sealed class Thread : CriticalFinalizerObject, _Thread
{
//
// 摘要:
// 将当前线程挂起指定的时间。
//
// 参数:
// millisecondsTimeout:
// 线程被阻塞的毫秒数。指定零 (0) 以指示应挂起此线程以使其他等待线程能够执行。指定 System.Threading.Timeout.Infinite
// 以无限期阻止线程。
//
// 异常:
// System.ArgumentOutOfRangeException:
// 超时值为负且不等于 System.Threading.Timeout.Infinite。
[SecuritySafeCritical]
public static void Sleep(int millisecondsTimeout);
}
继续跑题,说下产品设计方面,在我们产品经理设计的商城页面里,其中,采购平台页面里有一个栏位叫最新上架:
在另一个一级分类频道页里,也有一个取数逻辑相同的栏位叫新品到货:
个人认为,全局角度来看的话,这2个栏位应该取相同的名字。难道同一个商城里你能有些页面称商品为商品而有些页面称商品为产品么?
BTW,老早就想写这篇博客了,总是找各种理由推脱。周二晚上下班和一同事一起乘公交回去,我告诉他我次日上班后就抽时间写一篇博客。谁知,到了周三中午我同事问我写了没有时,我却发现我由于工作忙给忘记了。——我借故忙给推脱了,直到现在,8月份的最后一个工作日。
说到忙,这段时间,精确的说,是有3个月了,是有些忙,倒是没少加班,每到周五晚又搭车80公里回家看孩子,每周一5点起大早又匆匆赶回来。为什么老回家?我家新添了两名小成员,我的双胞胎女儿,小飞飞和小扬扬,真是不知不觉,她们已经两个半月大了,这期间的每个日夜,妻子默默付出了很多。。。
当pageIndex遇上pageNo的更多相关文章
- MVC遇上bootstrap后的ajax表单模型验证
MVC遇上bootstrap后的ajax表单验证 使用bootstrap后他由他自带的样式has-error,想要使用它就会比较麻烦,往常使用jqueyr.validate的话只有使用他自己的样式了, ...
- 敏捷遇上UML-需求分析及软件设计最佳实践(郑州站 2014-6-7)
邀请函: 尊敬的阁下:我们将在郑州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实 ...
- 敏捷遇上UML—软创基地马年大会(广州站 2014-4-19)
我们将在广州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战技巧. 时间:2 ...
- 敏捷遇上UML——软创基地马年大会(深圳站 2014-3-15)
邀请函: 尊敬的阁下: 我们将在深圳为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战 ...
- 初识genymotion安装遇上的VirtualBox问题
想必做过Android开发的都讨厌那慢如蜗牛的 eclipse原生Android模拟器吧! 光是启动这个模拟器都得花上两三分钟,慢慢的用起来手机来调试,但那毕竟不是长久之计,也确实不方便,后来知道了g ...
- SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败解决方案
SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败的问题,可作如下尝试: 更新失败后,在windows的[事件查看器→应用程序]中找到来源为MsiInstaller,事件ID为1 ...
- 当创业遇上O2O,新一批死亡名单,看完震惊了!
当创业遇上O2O,故事就开始了,总投入1.6亿.半年开7家便利店.会员猛增至10万……2015半年过去后,很多故事在后面变成了一场创业“事故”,是模式错误还是烧钱过度?这些项目的失败能给国内创业者带来 ...
- LoadRunner - 当DiscuzNT遇上了Loadrunner(下) (转发)
当DiscuzNT遇上了Loadrunner(下) 在之前的两篇文章中,基本上介绍了如何录制脚本和生成并发用户,同时还对测试报告中的几个图表做了简单的说明.今天这篇文章做为这个系列的最后一篇,将会介绍 ...
- LoadRunner - 当DiscuzNT遇上了Loadrunner(中) (转发)
当DiscuzNT遇上了Loadrunner(中) 在上文中,介绍了如果录制脚本和设置脚本执行次数.如果经过调试脚本能够正常工作的话,就可以设置并发用户数并进行压力测试了. 首先我们通过脚本编辑界面上 ...
随机推荐
- CAD二次开发---导入外部文件中的块并输出预览图形(五)
思路: 1)首先要定义一个数据库对象来表示包含块的文件,改数据库对象会被加载到内存中,但不会被显示在CAD窗口中. 2)调用Database类的ReadDwgFile函数将外部文件DWG文件读入到新创 ...
- spfa判断负环
会了spfa这么长时间竟然不会判断负环,今天刚回.. [例题]poj3259 题目大意:当农场主 John 在开垦他的农场时,他发现了许多奇怪的昆虫洞.这些昆虫洞是单向的,并且可以把你从入口送到出口, ...
- ftp 服务器搭建和添加用户和目录
安装: yum install -y vsftpd 修改配置: vsftpd.conf 修改:anonymous_enable=YES 改为:anonymous_enable=NO 启动/停止/重启 ...
- Android本地数据存储复习
Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...
- 黑马程序员_Java基础:序列化(Serializable)与反序列化
------- android培训.java培训.期待与您交流! ---------- 在学习IO中的ObjectOutputStream和ObjectInputStream时,会涉及到序列化和反序列 ...
- WInform关闭程序的几种方法以及区别。
1.this.Close(); 关闭窗体,如果关闭的是主窗体 程序结束.2.Application.Exit(); 退出所有的窗体但是如果有托管线程的话无法完全退出3.Application.Exit ...
- Windows XP和Word 2007不能正常使用VSTO插件
今天帮助同事解决了一个小问题,就是在WindowsXP上,为Word2007开发的插件不能正常显示. 通过搜索关键词 WindowsXp Word 2007 VSTO找到了两个解决方案. http:/ ...
- install openvpn and openvpn manager in ubuntu
sudo apt-get install openvpn sudo apt-get install network-manager-openvpn
- CCNA第四章第五章Cisco的IOS与SDM及其管理考试要点学习笔记
1. IOS的用户界面 Cisco互联网操作系统(IOS)是思科路由器和大多数交换机的核心,它是一个可以提供路由,交换,网络互联以及远程通信功能的专有内核. Cisco路由器的IOS软件 ...
- Android中自定义checkbox样式
1.首先在drawable文件夹中添加drawable文件checkbox_style.xml.