业务开发的一点小经验

也接触到开发大概1年多了,从netty技术栈到spring技术栈,先后也接触到了两种截然不同的项目:java服务器与大数据web,大概也有了一点对开发的认识,所以打算写下来记录一下。
 

1.git 分支的使用

        开发一个新功能时一定要拉出一个分支来,这样既可以在开发的时候避免其他变量的影响,也方便发布的时候方便选择,也方便回滚。
 
 
 

2.不要使用异常作为流程的控制因素

        之前有看到一些代码(包括我自己写的),竟然将异常作为一个流程控制的变量使用,真是一言难尽。无论如何,异常是系统本身的问题,而不是业务本身的问题,异常不应该作为业务逻辑的一个控制变量使用。
 
 
 

3.尽量不要使用非常复杂的继承体系

        对于java这种纯OOP思想的语言来说,使用继承是很天然的事,而且实际上使用起来也很实用。但是,凡事有利必有弊,有些时候程序员为了获取更高的扩展性(OOP的天然属性),在一个继承体系里面扩展了5、6层,甚至更多。这样每次扩展的时候,只需要扩展某一层里面的抽象类或者接口,而不用使用全新的体系,但是这样对于新上手的程序员来说是非常痛苦的,而有时候对于比较上游的修改对于老手来说也是非常可怕。因此,结合我的经验,java可以使用继承而且应该使用继承,但是继承体系大概2-3层就比较好,不要想在一个接口里面做完所有的事情。如果一个业务过于庞大,就要考虑将业务切分成更多的小模块,使用组合而不是继承来完成业务 。
 
 
 

4.集合类尽量不要使用null

        作为旧时代的残余,空指针一时爽,但是使用起来那不是一般的酸爽。尤其在java上来说,几乎每一段代码都有空指针异常抛出的可能性(吐个槽,scala那种从jvm衍生出来的语言保留null是没有办法的事,但是像go这种新生的语言竟然还保留nil那就是不知道怎么说好了,还有频繁的error!=nil)。因此,如果一个方法的返回体是集合的话,尽量不要使用空指针返回,而是返回一个初始化的集合实例,因为很多时候我们在获取到一个集团的时候会使用foreach循环来读取内容,如果集团为空时是不会对结果有影响的,如果这时候使用了null,那就惨喽。
 
 
 

5.工具类方法尽量要线程安全

        很多人使用一个工具类的时候,喜欢将一些频繁出现的变量声量为类私有变量,而不是声明为方法的局部变量。这样虽然是好看了,但是一旦线程访问多了,非常容易出现问题,而将变量局限于方法内部的话,无论多少线程进来,这个变量的生命周期都只存在于线程栈当中,不会被其他线程所影响,是线程安全的。工具类的私有变量应该声明为final或者类似性质的。
 
 
 

6.并发时应当尽量将变量线程隔离

        这个是什么意思呢?来个示例,例如一个web页面有10个图由10个后台接口对应,现在要在后台生成这10个图的excel,怎么弄呢?最原始的办法当然是按接口顺序来一一调用接口,而生成对应的String 集合,再写到excel文件里面。这样肯定是可以的,但是非常费时。更好的办法当然是使用并发,如果是spring技术栈的话,可以使用@async来控制,但是呢我们导出的excel顺序必须按页面的顺序来,不能乱序。于是可以使用10个@async接口先统一开始调用对应的方法生成一个future列表,再逐一get出来结果,这样我们在处理前面的结果时后面的接口也在进行,可以节省很多的时间。但是这样还是要有等待,不能按最长的接口调用作为最终的耗时判断,而且在开始时就生成future这样对代码的理解非常不利。
        这个时候,可以考虑到java的引用传值的特点,直接向异步方法里面扔入一个CountdownLatch、放置结果的集合与对应的参数,异步方法结果时使用count.countdown来发送信号 ,主流程使用预先放置好位置的集合来保证结果的顺序并await各个线程的结束。这样既可以减少时间,也非常好理解业务代码。而且这样,每个线程处理时,结果互不影响,颇有go channel那样的感觉,感觉不能太赞。
 
 
 

7.每个业务层应该只处理自己的业务

        这个经验呢主要是对web开发来说的(没办法,我已经被深深打上了spring的印记)。对于web来说 ,controller应该只处理前后端交互的事情 ,而service只处理业务逻辑代码的处理,dao不用说只应该处理持久化的东西。之前的代码呢,由于用上了缓存,之前的同事使用一个很复杂的service继承体系来处理固定的缓存操作,即在抽象类当中定义逻辑 1.将前端传入的查询参数初始化(这个由子类处理),2.执行缓存查询(如果有,直接返回,由抽象类执行),3.执行业务查询并缓存(这个由子类处理)。
        这个逻辑简单清晰,但是也有槽点。步骤1,前端参数的初始这种活应该由controller类来执行,而不应该放到service来操作;步骤2的取缓存这样完成跟业务逻辑没有关系的操作就不要放到业务层了,直接由AOP层来处理不是挺好

 

posted @ 2017-12-15 10:57  小小的平庸  阅读(379)  评论(0编辑  收藏  举报