赞
踩
最近又参与了一个项目的开发,感觉槽点颇多,特此记录。毕竟人总是更容易发现别人的缺点,但是我希望这些问题在我自己遇到的时候可以更好地解决,而不只是停留在无脑吐槽上。当然,对于好的地方我也该化为己用。多说无益,下面进入主题:
之所以先说产品迭代,是我个人觉得垃圾代码很多时候是由于过短的开发周期造成的。在变动需求后,软件架构却并没有足够的时间调整和重构,特别是项目刚启动的时候。不过话说回来,对于一般的产品而言能正常运行就足够了,毕竟花过多的时间菜都凉了。
有一天刚改完需求,然后对照下原型,才发现TMD傻逼产品把需求改了都不通知下。而且有时候测试时会根据测试人员的体验反馈修改需求,也是通过测试来告知的。虽然这些原型管理系统有修改后提醒的功能,但是那个东西响应太慢了,而且变更信息太多,一般都不会关注。所以,当涉及对正在开发的需求进行变更时,最好有个有效的通知,我们这种小团队微信 at 一下就行的事。
代码中充斥着大量重复的逻辑,比如一个组件可能他会选择复制多份代码而不是抽象一个组件类型,如果一个属性他可能多个子类都有单独添加却不写到父类里。不过这也可以理解,复制粘贴确实能快速完成需求开发,只是增加后期维护成本。
除了重复代码,还写了大量的全局信号,这也增加了各模块的耦合度。有的操作明明模块内部就能处理,但是他会触发全局信号,再在模块内部关联全局信号去处理。我认为应该把不必要的全局信号重构掉,组件或模块尽量保持独立,同时,那些零散的全局属性/信号可以分类给各个全局对象/单例来管理。
对于各种图谱的绘制也算是项目比较核心的功能,但是封装确实很糟糕。参照各种图表库,都会把图表的各个组件单独封装,而不是杂糅在一个 paint 事件里。我之前也做过一个简单的图表组件,参照 qcustomplot 和 qtchart 进行的抽象,但是也很多槽点。目前我的设想是抽象为节点树的形式,大致如下:
- Item{
- anchors.fill: parent
- PlotSource{ //数据源
- id: data_src1
- }
- PlotSource{
- id: data_src2
- }
- //一个chart可以有多个series谱线,共享chart的axis
- WaveChart{ //频谱图在上
- width: parent.width //布局同qml
- height: parent.height/2
- xAxis: XAxis{ } //x轴
- yAxis: YAxis{ } //y轴
- WaveCursor{ } //光标十字线
- WavePosition{ //竖线,用于标记当前位置
- id: position1
- attach: position2 //和另一个标记共享位置
- }
- WaveSeries{ //波形
- id: wave1
- color: "red"
- source: data_src1
- SeriesMark{ }
- SeriesHilight{ }
- }
- WaveSeries{
- id: wave2
- color: "blue"
- //一个图里可以有多个数据源的线
- source: data_src2
- }
- }
- RainChart{ //瀑布图在下
- y: parent.height/2
- width: parent.width
- height: parent.height/2
- source: data_src
- WavePosition{ //竖线,用于标记当前位置
- id: position2
- attach: position1
- }
- RainSeries{
- source: data_src1
- }
- }
- }
作为一个小团队,也没有什么独立的开发文档,我认为这种情况多写代码注释是很有必要的,除了接口注释,还应该把一些复杂的流程写备注下。而且注释是给各个开发成员一起看的,应该保持通用性,不标准的英文或者一堆缩写英文写了难道是给自己一个人看么(对,我说的就是算法接口里的塑料英语注释)。
有的人可能会说好的命名不需要注释,我只能呵呵哒。注释不仅说明了函数作用,参数含义,对于复杂的逻辑还应写出细节。除了接口,函数实现中也是需要写注释的,好的注释也能帮助自己理清思路。以前我也没那么注重写注释,但是维护或者改需求时经常遇到看不懂的地方,完全是浪费时间。
很多地方操作了指针或者容器,但是没有进行异常值判断,这恐怕是这个项目BUG众多的主要原因之一了。
在调试的时候也可以看到大量的异常提示,但是有部分是没有进行处理的。
目前这个软件加载动画着实很鸡肋,因为大部分初始化逻辑是在主线程进行的,所以启动的时候其实已经开始加载了,此时动画是被阻塞的,等加载完了动画继续跑。
从他的代码逻辑看,并没判断什么加载状态值,单纯的只是播放个动画,简直了... ...
- Timer{
- id: splashTimer
- repeat: true
- triggeredOnStart: true
- interval: 200
- onTriggered: {
- progressControl.value += 0.04
- if(progressControl.value > 0.999)
- {
- splashScreenLoader.item.visible = false;
- }
- }
- }
项目中涉及多线程的地方存在很多问题,比如该锁的没锁,容易遇到指针或者容器异常访问。比较离谱的是有一次多线程操作遇到 BUG ,修复的人直接把锁给注释了,后面遇到容器 pop 异常我又加了回去。
多线程共用的一些标志一般也是用的 bool 而不是 atomic 标志,也是一个隐患。
作为一个非开源的商用软件,代码里居然用到了 GPL 协议的库,这算是开发经理的责任么?(GPL 在分发时须附带源码,但是这个项目软件明显是不卖源码的)
UI细节没有参照设计稿实现,下面左为设计稿,右侧为实现:
有些地方使用的绝对坐标布局定位,修改UI时很麻烦。我刚入门的时候也犯了这个错误,少部分这么写还感觉不到,量大了就不好改了。
很多地方的代码没有格式化,东倒西歪的都没对齐,影响观感:
这个不是吐槽。感觉目前自己写的东西没有对调试信息和日志进行很好的管理,都是很随意的加个打印语句或者调试信息,然后看的时候再大海捞针。后期可以对日志或者调试信息分级分模块进行管理,方便找问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。