开发实践思考(五)

开发实践思考(五)

本篇接上一篇《开发实践思考(四)》,继续汇总日常总结点,每篇10个。

1. 思考

不要一直低头做事,要抬头思考。

人不能从重复的事情中获得成长。

做事闭环,一件事有始有终,让正确的事情,持续发生。

所谓靠谱的人,就是做到:凡事有交代,件件有着落,事事有回应。

凡事有交代:一件事要有推动过程中要有及时交代,在过程中有没有解决不了的问题,突发情况是否会影响事情进展,结果是好是坏,都要让与这件事相关的人清楚、马上知道。

事事有回应:体现的是一个人内心的责任感,是对他人起码的理解和尊重。

件件有着落:按照既定时间或计划,或者约定固定时间周期反馈工作进展。

当日事,当日毕。当周事,当周毕。

2. 代码注释

尽量使用有表达力的代码来代替注释,但以下类型的注释不应该省略:

  1. 组织以及法务信息
  2. 对意图的注释,既为什么要这么做
  3. 与常规处理不相符的地方,注明需求单号以及业务特殊处理的简要说明。

没有用的代码,要坚决去掉,而不是通过注释来掩盖它。

写对 code review 友好的代码:

  • 多行注释也用 //, 不用 /**/,这样有助于在代码对比软件中查看。
  • 改动的影响范围,要始终挂在心头。
  • 遵守一次提交只解决一件事的准则。

3. 需求讨论

在进行需求讨论时,心中要区分技术方案和业务方案,不要在需求讨论阶段过多涉及到具体技术细节。这里,笔者感觉考虑技术实现的限度。作为实现方,可以简单提下:

  • 针对该需求,目前技术框架大概能做到什么样的效果,如有类似效果的功能模块,可一并提出。
  • 针对需求要求的特殊效果,尽量向通用效果上去靠,如实在不好实现的,不要贸然下结论说不做,而是提出需要调研下,看现有能否支持,如不支持,衡量增加支持的改动成本以及相关收益。

除开上述两点之外,在讨论时,要更多地从开发角度来简化业务流程。主动思考达到同样的目标,有没有更加简单直接的方式?

第二点是考虑业务流程中的异常处理。一般的业务流程大多描述的是正常流程,在实际开发时,会有很多异常情况,针对这些异常情况的处理流程,是需要重点讨论的。产品从需求角度,很难考虑完全异常情况,开发参与需求讨论需要强调这一点。

第三点,对需求中什么是重要的功能,什么是无关紧要的功能,达成一致意见。在开发资源有限的情况下,重点讨论和完成重要功能。

第四点,在进行需求讨论之前,将待讨论的需求文档发出来,让参会者有个初步的认识,这样好在讨论会上有更加深入的讨论。

第五点,当需求中涉及UI、产品、开发各方面意见时,作为核心的产品,不能只当各个参与方的传话筒,而是要根据自己对产品的理解,将别人的诉求或者说要求转换为可供讨论的事项,并推动各方达成一致认同。如果仅仅是转发UI的建议,直接贴到讨论群里,其他参与者还要理解UI的建议,并据此作出各自的判断,这种讨论效率,不如产品与UI讨论梳理后,直接给出结论,讨论该结论是否可行来的直接、高效。

4. 重构小技巧

在准备使用新功能替换旧功能时,新旧功能涉及到的界面较多的情况下,强烈建议保持原有功能,新的功能采取逐个替换的策略,完成一个界面之后,需要反复查看该实现,简化相关操作,直到每一步操作都是必要的,做好一个页面后,其他类似页面可参照修改。

重构类成员函数

当在基类中提供函数A,随着不断的使用,发现该函数需要改进,但直接修改,会影响外部众多使用者,这时如何做呢?

可行的重构方案如下所示:

基类A:


class Base
{
	public:
		void fun();
}

// 使用方式
Base a;
a.fun();

功能派生类B:


class Derive : class Base
{
public:
	void funXXX();

private:
	void fun();	 // 将基类同名函数设置为私有,防止外部使用
}

// 新的使用方式
Derive a;
a.funXXX();

上述这种做法,可使得重构后,使用新类的,只能使用新版本的函数,不能使用旧版本函数。逐个进行替换修改,让编译器帮助检查错误。

5. 功能可配置

警惕功能的可配置性,不要觉得加上可配置后,整个项目就更胜一筹。可配置性只是锦上添花,更重要的是,不是说系统支持可配置,就要在任何地方都提供可配置功能。

极端点说,如果一切都可配置,那么一切都没有可配置的意义。提供策略以及使用策略的机制要谨慎,不要引入那些不必要的可配置功能,使得整个系统过于复杂。

6. 代码合并

合并代码的实践经验:

  1. 从分支合并到主线,只合并自己的提交,不要擅自合并他人提交,因为你不知道其他人提交背后的逻辑以及关联关系。

  2. 单次合并控制在5~10次提交以内。如果单次合并太多,可能会有多个冲突要解决,这些冲突之间有可能有先后关系,增加解决冲突难度以及出错概率。

  3. 从分支合并到主线,要包括源文件的父目录以及上层目录,直达工程根目录。这样,可在后续的合并中,可查看到该次提交是否已合并到主线上。

  4. 当你的修改依赖其他人的提交,而其他人尚未合并到主线上来。这个时候如何处理?
    方法一:通知其他人,将你依赖的部分先合并到主线上,然后你在提交。
    方法二:自己合并依赖其他人的部分,并通知相关人员。

    推荐使用方法一。

7. 代码提交

在平时的工作中,从提交记录上看,感觉有些同事的代码提交很随意。

  1. 有同一个文件,一会儿提交一次,一会儿又提交一次,看下改动内容,应该是在修改时漏掉了某些地方,紧接着再打一个补丁。

  2. 在不同业务模块(例如A、B、C和D)中,同样的功能都受影响。该A模块后提交一次,改B、C模块时再提交一次,改D业务提交一次。这种方式,感觉没有一次把一件事做完,会不会还有其他模块也有同类问题,但是改漏了呢?

笔者的观点:

针对问题一,能不能在提交前,仔细回顾下提交改动范围,多考虑下发生场景,有没有同模块下其他函数也有类似的问题,可以一并改完,自测完再提交。

针对问题二,能不能将不同业务中的同样功能提取出一个独立模块,其他业务方都调用该模块,有问题只改这个模块。如果不方便提取的话,要求低一点,能不能同类型的修改,合并为一次来提交。这样,既方便审核者的审查,也方便自己后续回顾。

代码提交注意事项:

  • 确保本次提交修改的范围在同一问题域下。如果是属于不同问题域的修改,要分为两次提交,不要混为一谈。
  • 确保在新增、删除文件或目录时,提交对应的工程配置文件。不要发生文件提交了,但别人更新后编译不通过的低级问题。
  • 提交时的注释要和提交的实质改动保持一致,如果改动较复杂,可简要描述修改方案,讲如何修改,不要涉及到代码细节。不要出现"挂羊头卖狗肉"的情况,例如:注释里说了A、B两点,实际改了A、B、C三点,或者是注释说改了A、B、C三点,实际只改动了A、B两点。

8. 第三方文档

第三方发过来的文档、设计稿、代码什么的,千万不要贸然修改,一旦有修改,就不好说清楚后续的维护者是谁了,会造成很多不必要的麻烦。

9. 团队协作

当涉及到跨团队协作时,你不清楚某个问题的负责人,于是就会询问多个同事。如果其中一个人向你解答,那么,除了向他表示感谢之外,还需要主动告知其他尚未回复你的人,此问题已得到别人的解答,以防浪费他们的时间。

更近思考一步,出现上面情况的原因是,某个问题无法找到对应的对接人,因此,会去询问多个。可以在组织层面上进行优化,这里我有几点想法:

  1. 部门对外提供的服务、接口文档是聚合形式,每个接口或者模块上要注明接口提供方,要具体到负责的接口实现者最好。
  2. 从内部来说,每个功能的负责人负责维护各自模块的功能说明以及注意事项,在一个公共wiki上对外提供服务,告知使用方。
  3. 对于新提供的功能或者重大优化,需要有一个对外宣传渠道,可通过向业务方进行培训、微信支持群、系统月报等各种推广沟通机制,将各类业务系统最新状态、各项需求的工作进度传达给业务部门。
  4. 为避免不同人针对同样问题重复咨询第三方,需要将经常咨询的问题做一个QA页面,任何人在询问时,先自助在QA中查询问题关键字,看能否解决,如果不能解决再去询问,得到确切答复后,记得把问题以及对应回复整理到QA页面。

10. c++构造和析构函数顺序

构造函数调用顺序:

  1. 基类成员构造函数
  2. 基类自身构造函数
  3. 派生类成员构造函数
  4. 派生类自身构造函数

析构函数与构造顺序恰好相反:

  1. 派生类自身析构函数
  2. 派生类成员析构函数
  3. 基类自身析构函数
  4. 基类成员析构函数
posted @ 2022-02-10 19:34  浩天之家  阅读(52)  评论(0编辑  收藏  举报