您当前的位置: 首页 > 

龚建波

暂无认证

  • 2浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

项目开发总结(吐槽)(2021-6-12)

龚建波 发布时间:2021-06-12 17:47:51 ,浏览量:2

最近又参与了一个项目的开发,感觉槽点颇多,特此记录。毕竟人总是更容易发现别人的缺点,但是我希望这些问题在我自己遇到的时候可以更好地解决,而不只是停留在无脑吐槽上。当然,对于好的地方我也该化为己用。多说无益,下面进入主题:

1.产品迭代周期过短

之所以先说产品迭代,是我个人觉得垃圾代码很多时候是由于过短的开发周期造成的。在变动需求后,软件架构却并没有足够的时间调整和重构,特别是项目刚启动的时候。不过话说回来,对于一般的产品而言能正常运行就足够了,毕竟花过多的时间菜都凉了。

2.团队协作

有一天刚改完需求,然后对照下原型,才发现TMD傻逼产品把需求改了都不通知下。而且有时候测试时会根据测试人员的体验反馈修改需求,也是通过测试来告知的。虽然这些原型管理系统有修改后提醒的功能,但是那个东西响应太慢了,而且变更信息太多,一般都不会关注。所以,当涉及对正在开发的需求进行变更时,最好有个有效的通知,我们这种小团队微信 at 一下就行的事。

3.代码封装差

代码中充斥着大量重复的逻辑,比如一个组件可能他会选择复制多份代码而不是抽象一个组件类型,如果一个属性他可能多个子类都有单独添加却不写到父类里。不过这也可以理解,复制粘贴确实能快速完成需求开发,只是增加后期维护成本。

除了重复代码,还写了大量的全局信号,这也增加了各模块的耦合度。有的操作明明模块内部就能处理,但是他会触发全局信号,再在模块内部关联全局信号去处理。我认为应该把不必要的全局信号重构掉,组件或模块尽量保持独立,同时,那些零散的全局属性/信号可以分类给各个全局对象/单例来管理。

4.对于图表组件的封装

对于各种图谱的绘制也算是项目比较核心的功能,但是封装确实很糟糕。参照各种图表库,都会把图表的各个组件单独封装,而不是杂糅在一个 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
            }
        }
    }
5.编码规范-注释

作为一个小团队,也没有什么独立的开发文档,我认为这种情况多写代码注释是很有必要的,除了接口注释,还应该把一些复杂的流程写备注下。而且注释是给各个开发成员一起看的,应该保持通用性,不标准的英文或者一堆缩写英文写了难道是给自己一个人看么(对,我说的就是算法接口里的塑料英语注释)。

有的人可能会说好的命名不需要注释,我只能呵呵哒。注释不仅说明了函数作用,参数含义,对于复杂的逻辑还应写出细节。除了接口,函数实现中也是需要写注释的,好的注释也能帮助自己理清思路。以前我也没那么注重写注释,但是维护或者改需求时经常遇到看不懂的地方,完全是浪费时间。

6.缺乏异常判断/处理

很多地方操作了指针或者容器,但是没有进行异常值判断,这恐怕是这个项目BUG众多的主要原因之一了。

在调试的时候也可以看到大量的异常提示,但是有部分是没有进行处理的。

7.关于软件启动加载动画

目前这个软件加载动画着实很鸡肋,因为大部分初始化逻辑是在主线程进行的,所以启动的时候其实已经开始加载了,此时动画是被阻塞的,等加载完了动画继续跑。

从他的代码逻辑看,并没判断什么加载状态值,单纯的只是播放个动画,简直了... ...

    Timer{
        id: splashTimer
        repeat: true
        triggeredOnStart: true
        interval: 200
        onTriggered: {
            progressControl.value += 0.04
            if(progressControl.value > 0.999)
            {
                splashScreenLoader.item.visible = false;
            }
        }
    }
8.多线程

项目中涉及多线程的地方存在很多问题,比如该锁的没锁,容易遇到指针或者容器异常访问。比较离谱的是有一次多线程操作遇到 BUG ,修复的人直接把锁给注释了,后面遇到容器 pop 异常我又加了回去。

多线程共用的一些标志一般也是用的 bool 而不是 atomic 标志,也是一个隐患。

9.其他问题

作为一个非开源的商用软件,代码里居然用到了 GPL 协议的库,这算是开发经理的责任么?(GPL 在分发时须附带源码,但是这个项目软件明显是不卖源码的)

UI细节没有参照设计稿实现,下面左为设计稿,右侧为实现:

有些地方使用的绝对坐标布局定位,修改UI时很麻烦。我刚入门的时候也犯了这个错误,少部分这么写还感觉不到,量大了就不好改了。

很多地方的代码没有格式化,东倒西歪的都没对齐,影响观感:

10.调试信息/日志管理

这个不是吐槽。感觉目前自己写的东西没有对调试信息和日志进行很好的管理,都是很随意的加个打印语句或者调试信息,然后看的时候再大海捞针。后期可以对日志或者调试信息分级分模块进行管理,方便找问题。

 

关注
打赏
1655829268
查看更多评论
立即登录/注册

微信扫码登录

0.1200s