# 程序员的八宗罪

# 重复造轮子

程序员都经历过“造轮子”的环节,是每个程序员的必经之路。

在学习源码,重复造轮子是一个能够提升自己综合代码能力的手段。但是在具体实际生产中,一般很少程序员会自己重复造轮子(大厂需求或者有高性能需求除外),因为自己造的轮子,一般都有以下缺点:

  • 缺少文档,不好维护
  • 消耗大量精力甚至价值
  • 普适性不高,代码运用场景较窄

# 过度封装(过度抽象)

之前共事的一个同事,用poi封装了一个ExcelUtils,并在公司宣传excel导出报表功能使用该工具类即可。在其为自己封装感到沾沾自喜的时候,另外几个开发小弟抱怨这个工具类不好用,原因是工具类相当不灵活,没有对应的表头修改功能,后来同事都没有人使用该类,都针对自己的业务场景使用原生poi进行数据导出功能开发。

之前带过一位外包同事,做一个上传身份审核资料的功能,资料有身份证(姓名、身份证号码、身份证有效期、图片)、营业执照(公司名称、执照号码、营业执照有效期、图片)、开户银行许可(许可号、图片)、手持身份证(图片)等。这位外包同事,建立的数据库表结构是:table (id、data_type、user_name、card_number、photo)。上传资料后,强行把字段存进这张表里,并且使用data_type类型进行区分。后面我本人对此感到不满意,但是由于准备上线的原因,就延迟到上线后优化,后来光是清洗数据都花了好长的精力。

针对上述问题,我认为过度封装和过度抽象有下列缺点:

  • 灵活性太低,可定制化程度太少
  • 未能合理考虑大部分的适用场景
  • 内聚性太高,可能内涵业务本身不需要的特性
  • 缺少对修改关闭,对扩展开放的思想

# 缺少封装

隔壁项目组传闻,有个同事写了一个1万行的订单类,在系统重构时,各位兄弟都苦不堪言。

原因是有位大佬需要改一个本身业务相当复杂的方法(约有千行代码),本身方法业务逻辑改动不多,只是改动了入口的参数。由于这位“大佬“担心影响到以前写的业务逻辑,直接把这个方法ctrl + c, ctrl + v,复制出另外一个方法进行修改。

这样做,会导致以下问题:

  • 冗余代码太多,严重降低代码的可维护性
  • 入口泛滥(下面会提到)
  • 入口区分性太低

# 修改口泛滥

有一天在开发时,看到一个类中有3个方法很有意思:

方法 作用 所属同事
addDeposit(Integer amount) 用于保证金充值,不记录操作人员,不写日志(数据库记录) 同事A
deductDeposit(Integer amount, User user) 用于保证金扣减,记录操作人员,写日志,格式为:XXX操作扣减保证金XX元 同事B
addDeposit(Integer amount, User user) 用于保证金充值,记录操作人员,写日志,格式为:保证金(增加/减少)XX元,操作人:XXX 同事C
modifyDeposit(Integer amount) 用于保证金充值或扣减(按照amount为正负区分),不记录操作人员,不写日志 同事D

大致查看了实现的业务逻辑,各不相同,也没有做好对应的数据校验,而且同事B和同事C的写日志逻辑都是各自实现的,同事各自开了不同的修改入口实现保证金操作场景下的操作,是在难以维护。在后面我仅保留了一个方法:

方法 作用 所属同事
modifyDeposit(Integer amount, boolean recordLog, User user) 用于保证金充值或扣减(按照amount为正负区分),可根据recordLog参数选择是否写日志,若写日志,格式为:保证金(增加/减少)XX元,操作人:XXX 大家共用

这样做的好处是:

  • 做到一改全改
  • 有利于代码的复查审核
  • 有利于功能的复用
  • 更有利于代码的规范化和标准化
  • 能够保证全局的领域事件抛出

# 未理解需求就动手写代码

在刚毕业工作的时候,血气方刚干劲十足,遇到需求就马上动手写代码,后来在后面吃了许多的哑巴亏:

  • 实现的逻辑压根不是产品想要的
  • 代码质量过低,BUG太多
  • 代码及其不优雅,可以使用设计模式简化代码的问题
  • 开发到一半,产品说需要做”小改动“,导致推翻重来
  • 开发到一半,发现产品功能不能形成闭环,需求回退到产品

后面我的做法是:

  • 在接到需求后,仔细端详需求流程和各个细节
  • 反复确认本次需求是否封板不做大规模变更,确认产品功能是否能闭环,各个新功能与存量功能是否有逻辑上的冲突
  • 思考功能逻辑是否实现过,是否有类似的功能场景可以借鉴,可以套用什么设计模式
  • 本功能是业务性功能还是非业务性功能?是新添加功能还是优化功能?以不同的处理态度(紧急/不紧急、是否考虑更强的扩展性)进行开发

# 不尊重约定和规范

下面是一个同事,我行我素的例子,后面被公司开除了:

实例 公司规范 某同事写
返回报文 {"code":0,"message":{}} {"isSuccess":0,"data":{}}
序列化和反序列化 使用Jackson 以速度更快为由使用Fastjson
接口管理 使用RAP2管理 在word文档中管理接口

# 没有分清技术与业务之间的关系

产品经理和开发人员之间的战争,已经从计算机诞生那一刻延续到现在了,我对两者的关系有以下的理解:

  • 其实技术与业务,不能单纯地区分独立,应该两者结合进行考虑。业务为技术提供了一个业务场景的温床,而技术则是业务实现的一个具体工具和手段;业务是技术宏观上的表现,技术是微观业务的分解
  • 在业务上,技术人员应该尽量满足原始业务需求,不应该一味有“抵触心理”,遇到一些难以实现或者运用场景不清晰的需求,可以和产品经理进行协商修改
  • 没有实际业务场景,技术人员何来有需求;没有技术人员,业务如何实现?市场如何快速占领?
  • 个人目前回更偏向于技术驱动,因为技术驱动更能节约后面业务实现所需要的进度和成本

# 心态不稳定

  • 遇到紧急需求,要心平气和
  • 有BUG是很正常的事情,无需过度紧张烦恼
  • 市场上,90%的程序员都会有加班的时候,所以,今晚你不是一个人在奋斗
  • 程序员生活会比较枯燥,有空多和异性或者其他行业的朋友聊聊天
  • 合理安排作息时间,降低脱发危险