作者发现,本文被多个博客和网站转发。赠人玫瑰,手有余香!
本文版权归作者和博客园共有,欢迎转载,转载请注明出处: 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的更多相关文章

  1. MVC遇上bootstrap后的ajax表单模型验证

    MVC遇上bootstrap后的ajax表单验证 使用bootstrap后他由他自带的样式has-error,想要使用它就会比较麻烦,往常使用jqueyr.validate的话只有使用他自己的样式了, ...

  2. 敏捷遇上UML-需求分析及软件设计最佳实践(郑州站 2014-6-7)

      邀请函: 尊敬的阁下:我们将在郑州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实 ...

  3. 敏捷遇上UML—软创基地马年大会(广州站 2014-4-19)

        我们将在广州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战技巧. 时间:2 ...

  4. 敏捷遇上UML——软创基地马年大会(深圳站 2014-3-15)

    邀请函: 尊敬的阁下: 我们将在深圳为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战 ...

  5. 初识genymotion安装遇上的VirtualBox问题

    想必做过Android开发的都讨厌那慢如蜗牛的 eclipse原生Android模拟器吧! 光是启动这个模拟器都得花上两三分钟,慢慢的用起来手机来调试,但那毕竟不是长久之计,也确实不方便,后来知道了g ...

  6. SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败解决方案

    SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败的问题,可作如下尝试: 更新失败后,在windows的[事件查看器→应用程序]中找到来源为MsiInstaller,事件ID为1 ...

  7. 当创业遇上O2O,新一批死亡名单,看完震惊了!

    当创业遇上O2O,故事就开始了,总投入1.6亿.半年开7家便利店.会员猛增至10万……2015半年过去后,很多故事在后面变成了一场创业“事故”,是模式错误还是烧钱过度?这些项目的失败能给国内创业者带来 ...

  8. LoadRunner - 当DiscuzNT遇上了Loadrunner(下) (转发)

    当DiscuzNT遇上了Loadrunner(下) 在之前的两篇文章中,基本上介绍了如何录制脚本和生成并发用户,同时还对测试报告中的几个图表做了简单的说明.今天这篇文章做为这个系列的最后一篇,将会介绍 ...

  9. LoadRunner - 当DiscuzNT遇上了Loadrunner(中) (转发)

    当DiscuzNT遇上了Loadrunner(中) 在上文中,介绍了如果录制脚本和设置脚本执行次数.如果经过调试脚本能够正常工作的话,就可以设置并发用户数并进行压力测试了. 首先我们通过脚本编辑界面上 ...

随机推荐

  1. C#中语音合成简单使用

    我使用的是vs2013 1.在项目中添加引用,项目->添加引用->COM选择Microsoft Speech Object Library 2.在需要使用语音合成的地方调用代码: SpVo ...

  2. S2SH简介

    struts2简介 Struts2是由WebWork基础上发展起来的,与struts1比较,选用struts2的理由是:①Struts1要求Action类继承一个抽象基类,而Struts 2 Acti ...

  3. 一台MySQL服务器启动多个端口

    一台MySQL服务器启动多个端口 在测试Mysql多主一从服务器,即一个从服务器多端口同步不同主库.本文记录了开启不同端口的操作. 详细步骤: 1.首先要先把my.cnf配置文件复制一份,开几个端口要 ...

  4. jQuery - plugin 代码模型

    1.扩展 jQuery 的全局函数,主要以 $.xxx() 的形式调用 (function($) { $.myFunction = function(array) { // code } })(jQu ...

  5. bond配置

    Bonding的模式一共有7种: #defineBOND_MODE_ROUNDROBIN       0   (balance-rr模式)网卡的负载均衡模式 #defineBOND_MODE_ACTI ...

  6. iOS后台定位时授权提示一闪而过的解决办法

    今天做后台定位时,授权提示"允许 XXX 在您并未使用该应用时范文您的位置吗?"总是一闪而过,点不到,或者压根就不弹出.后来找到了解决问题的方法,那就是:将CLLocationMa ...

  7. disconf安装部署

    1.client pom文件引入 <dependency> <groupId>com.baidu.disconf</groupId> <artifactId& ...

  8. linux(centos)源码安装git

    最近使用一个开源库,部署的的时候需要用git克隆依赖库.刚好系统没安装git.就尝试了源码安装git. 源码下载地址:http://codemonkey.org.uk/projects/git-sna ...

  9. hdu 5944 Fxx and string

    \:nn,下标从1开始,第\:i\:i位的字母为\:s_is​i​​,现在Fxx想知道有多少三元组\:(i,j,k)\:(i,j,k)满足下列条件 1.i,j,k\:i,j,k三个数成等比数列 2.s ...

  10. yii2 mpdf

    安装 php composer.phar require kartik-v/yii2-mpdf "*" 或者把 "kartik-v/yii2-mpdf": &q ...