0
点赞
收藏
分享

微信扫一扫

开发那点事(1)——浅谈开发的思路

这又是一篇记录+闲聊+整理贴。最近在一个人做一个不算很小的项目,所以想把思路和一些设计整理下来,方便以后遇到相同需求可以快速的有思路,如果能顺便帮助一头雾水的别人那是更好不过的了。
首先说点闲话,工作以来没去过大公司,团队人数最多的就是第一家公司,标准外包续命的有自己理想的一家公司。老板是个老技术,也是我至今为止都非常感谢的一个人(虽然现在没有联系了)。现在的代码书写的习惯,项目开发的流程和思路,一些常用工具类的使用等,都是那时候学会的。在此也祝那家公司越来越好吧。

初中级程序员日常工作

首先,这么多年工作以来,也做过不少的项目了,有二次开发的,有项目重构的,有维护现有的,也有从0开始的。而二次开发又分为从头开始和接手原来的。
反正目前为止我差不多都做过。这里简单的截个图表示下我自己的理解(个人理解,错了或者不全欢迎指出,但是不接受恶意攻击)。



因为我毕竟经验也就这么多,所以不敢说我理解的就很全面了。但是这些都是我遇到过,经历过的。简单的说下目前为止待过三家公司。

  • 第一家工作时间最长是个7个人的外包公司,然后大大小小的接过很多个项目。一个星期一个小程序之类的很正常。剩下网站,app等都有涉及。其中从0开始做项目比较多,但是这期间也接过一次二次开发的项目。就是甲方之前自己养个团队开发,一年多了也没出完整结果,所以后来直接找了我们二次开发。
  • 第二家公司的个创业公司,老板用php写了一个项目,但是因为考虑到性能还有其他原因吧,所以只招了我一个java程序员,还有一个前端,想要用java重构这个项目(最后因为种种原因所以还没重构完我就离职了)。
  • 第三家公司就是现在写这篇笔记时所在的公司。我们公司是做自己的产品的,不过在我入职的时候这个项目已经接近尾声。另外还有个16年的项目也在维护。所以入职后工作内容百分之二十维护老项目,百分之三十是自己的产品修修改改,没事加个功能加个接口啥的。比较大的改动就是其中有两个模块是后来要去添加的,所以从数据库到代码逻辑流程都需要重新定义,和之前的业务等关系也不大,我把他定义为二次开发的一种。另外百分之五十就是现在,因为疫情原因所以公司有一定的困难,而且推广遇到很大的阻力,所以2020年的工作计划是外包续命。

简单的叙述一下工作经历,然后各个岗位和不同公司中主要的工作内容也简单说了下。剩下的一些别的内容,比如写个专利书,写个说明书,写个软件著作权,写个三级等保申请之类的感觉是杂活,工作中都用到了,但是没啥意义。所以不多说了。
对了,一些常用的第三方接入什么的,例如阿里云,腾讯云的一些设置配置,获取小程序appid,appKey啥的,这些有的也算是工作中一部分,比如我第二家公司这些所有的配置,或者说买什么服务也都是我在做,花多少钱直接找老板报销。但是第一家公司这些都是老板处理,我需要什么直接朝他要就行了。至于现在这家属于有些自己要弄,有些要找领导要。反正这些都不难,自己看人家的官方文档啥的就行了。
毕竟开发岗位最终肯定还是要落实到开发和代码上。

从需求文档开始

其实这个没办法一概而论的给一个思路解决所有问题,针对我自己遇到的这么多的工作中也有不一样的侧重点。但是熟读需求文档绝对是所有开发的前提。
而且我的习惯是熟读开发文档,在脑子里先过一遍怎么实现。而且需求文档上经常会有一些坑,需要我们自己注意。打个比方,如下截图是我们需求文档中截取的一部分内容:


说实话,没打马赛克的用户信息除外,积分,等级,勋章,签到不算标点符号就八个字。
但是呢?仔细想想这八个字后面是什么。

  • 积分:是不是需要一套完整的积分体系?是每天登陆给一定积分,还是在线一定时间或者做了什么动作给积分?
  • 等级:用户等级怎么判断,消费到多少还是注册多长时间还是做了什么动作升级(虽然这个一般是和积分关联的)?
  • 勋章:勋章最基本的要有个勋章库吧?比如有什么种类的勋章,每个勋章的获得条件之类的。
  • 签到:首先一天的签到是好做的,但是这个签到要在哪里用到?怎么展示?可不可以补签?是展示本月的签到情况还是可以查询所有的签到情况?

说实话,上面的八个字四个词可以延伸出来的东西很多。甚至细节上的实现也各有不同。虽然都是基本功能,但是我在看了需求文档后还是和领导仔细询问了,并且我个人的习惯是问清楚了,并且记录下来,把文件也发给领导确认没问题了然后才会去做。这样以后如果有改动或者如果说做出来甲方说和他想要的不一样我也有话可说,这个习惯我也推荐给大家,做之前一定要把需求确定了并且砸实了。当时在第一家公司我就受过这个坑。


不懂就问,确定再做

那时候入行时间也短,当时是一个搜索的功能,甲方的需求说只需要输入名字查询。我就只简单的做了个搜索,并且当时是口头上确认了,可能我没说清楚,甲方的人也没注意听。反正我说这块这么做那边的人肯定是说ok了。但是等实现了以后甲方测试软件的时候,说这里和他想要的不一样。然后我当时说都确定了的,你们也同意了的,但是甲方就是说没有。然后我当时也懦弱,好一点的是这块内容不是那么难改动,所以最后改完了。然后我们老板把我骂哭了。哈哈,真的是哭了一个多小时吧,一方面的委屈,另一方面是恨,我拿着炸药包炸当时对接的甲方的家的心都有了。还有一方面是对自己的恨,当时对接我什么证据都没留下,所以才造成了现在的一切。反正哭了一个多小时之后,再做什么都习惯性用文件和文字的形式来交接和确认。哪怕有时候和领导口头上谈成了什么我都会用文档微信发给领导或者用文字发给领导再确认一次。有时候不要怕麻烦,也不要怕麻烦别人。毕竟多确认一下浪费不了多少时间,你不能确定和你对接的是人是狗。所以。。。


好了,上面就是一个过来人的简单建议。然后继续说这个需求的八个字,不确认好了匆匆做出来,如果发现甲方的一些奇葩要求目前的设计不好实现或者不能实现,那就尴尬了,所以说我的建议熟读需求文档,一点点在自己脑海里建立一个完整的模型。大概做到闭上眼睛能把这个项目从头到尾跑一遍而不卡壳。同时把这个讲给甲方或者领导听都没有异议再开始真正的做。
这个还是要感谢第一家公司,让我学会了简单的word画图。比原型图还要简陋也没关系,丑也没关系。但是按钮,模块,跳转关系啥的写清楚就好。把整个项目的草图画一遍,加深了自己对业务的理解,也让自己的逻辑关系数据关系有个完整的建立。



这个图我自己看都辣眼睛。。反正就这样了,黄色的代表点了要走接口的。白色就是写死的。点了不走接口的,前端爱咋做咋做吧。然后这个页面是我觉得用户那个页面的。划重点!!这个图是我为了展示出来特意画的!!正常我给自己和领导看的比这个还要丑。。。但是画的丑时间也快,就是两分钟一张图的那种。之前的龟毛同事,一个后端话这种图画出来跟原型图似的。。说真的一方面挺佩服画工好,另一方面话这个草图能画一天也是佩服了。反正这个就是个人的建议。但是这么做的好处是每一个图都对过以后,照着图来做,不容易出错。
然后好多时候需求文档可能不是很专业,所以有问题一定要在设计之前就解决了!不然可能做的时候坎坷的多。反正目前来讲我只和领导还有甲方对接过,听说大公司是有专门的项目经理的,唔,羡慕。
然后如果你画不出这个图的流程,或者说你自己脑子里不能顺下来就说明你对需求还是不熟,一定不能抱着对付的心态开工。
正常我个人来讲,我觉得单单是看需求文档就是一个5个工作日的工期(以4个月开发时间来讲)。然后下一步数据库设计又是一个星期。

数据库设计

上面我说了,数据库的设计一般也是一个星期也就是5个工作日的工期。这里先熟悉了业务流程和逻辑,对我们设计数据库的表等好处是大大的。
我简单举两个例子:

  • 比如钉钉上的上下班签到,甚至能往上翻记录的,这种最好每个用户每次的签到单独记录一条数据。因为除了签到还要具体的时间。
  • 再比如牛客上的打卡学习,说实话我不知道人家怎么实现的,但是只能打完卡显示打卡数+1,也不能具体查看哪天打卡了,也没别的地方展示。我觉得可以做累加。每个用户对应签到天数。然后打卡的按钮一天只能触发一次(前端实现)。打卡就+1就好了,这样做多简单又方便。不过人家不一定做得这么low,我就是猜的。

反正这就是说明一个简单的签到功能不同设计的数据库也不同。所以说数据库的设计一定要依赖于具体的业务。
我是打算有时间把这些常用的业务的数据库的常用设计整理下。比如说权限控制的数据库,我一直习惯于用shiro的那五张表实现。虽然不用或者不那么做也可以,但是习惯了。
还有算是常用的好友是单向好友还是双向好友啥的。设计成多对多比较灵活。
关注,收藏什么的。这些其实都有一些常用是设计(我反正知道的大多数为了灵活性而增加记录的条数)。但是之前也做过一个点赞功能,是点完赞不能取消的,所以是用点赞用户名的拼接实现的。缺点也就是点完赞取消啥的不好做。

  • 角色表: 另外我这边的做法是所用用户一张user表。然后具体的角色比如商家,客户,管理员,客服,主播等角色再用另外的表写各自的信息,然后做外键关联。感觉这个也是常规做法。
  • 订单表: 因为我这个项目算是电商项目,所以订单必不可少,订单商品一对多,还有订单和物流单一对一之类的,都是常规做法。
  • 商品表:商品表其实大多数都是差不多的,不够个人做法是商品表保留整个商品介绍的html页面。这个也是以前开发用过的套路。因为有的是允许自定义展示模块的。反正我只能说这些都不是硬性要求而是个人习惯。实现的途径从来不是一个。
  • 银行卡表: 这个肯定不是在用户信息里面,毕竟这种涉及到了私人信息。现在又分支付宝微信啥的。有的是调起本手机的微信/支付宝。有的是指定的支付宝(比如淘宝支付只会调起绑定的支付宝。)具体怎么做都和需求紧密相关。

这里我就简单的说一些常用的功能的设计,而且说得也很不清楚,毕竟这个不是重点,重点是要认识到:最合适的数据结构是根据需求设计的,而不能盲目的跟风。我早就说过这个态度:不要大佬说点什么就当成圣旨,因为人家说的是常用的模式,但是谁知道你们开发有什么奇葩需求了?
反正我对这块的态度是不要急,一点点构思,一遍遍看。慢工出细活,我不能说百分之百,但是百分之八十随着项目做着做着要不断修改表中字段,添加关系甚至添加表都是因为最开始的数据库设计有问题。所以后期不断返工,不断改动。
当然了从设计完到做完项目一次数据库不改也不太现实。但是改动频繁肯定也是有问题的。
打个比方,前几天做的那个app,领导当时说半个月做完,然后看了需求文档觉得蛮简单的,我就偷懒了简单用半天勾勒一个数据库关系图就上手,虽说主体还是对的,但是几乎每个表都加过字段,甚至有的今天加一个,明天加一个,后天加一个的加。也亏得是逻辑简单,加个字段的成本比较小,不过复杂的业务这么改动谁也受不了。
所以数据库的设计关系到以后开发的速度和代码的可读性和逻辑性。我记得听过一句话:究竟数据库该怎样设计,古往今来,每一个人都有每一个人的想法,所以数据库设计并没有优劣之分,好坏之别,合适的数据库设计就是最好的。
我觉得这这句话说的真的很好,数据库三大范式我知道,但是好多时候问数据库设计或者说问多表联查,我都会说非特殊情况除外,需要跨太多表联查只能说明是数据库设计有问题。有时候数据库适当的冗余真的很有必要。说了这么多其实好多时候字段的定义,关联关系等主要还是时间的累计。有时候一个不怎么好的设计会让你知道下次怎么做能更好。
另外多学,多用,多看,多想总是有用的。

接口的定义

这个其实是分歧最大的一个,在我看来也是最难的一个。接触过很多前端,从最开始工作四五年的小姐姐(第一家公司的元老人物,我目前为止认为技术最好的 一个人),到后来的小菜鸟实习生。到中间私活的甲方提供的前端。还有现在的前端同事。
怎么说呢,我经历过很多次接口定义好了,代码差不多写完了,结果前端小哥哥小姐姐或者苦着脸或者小心翼翼也有理直气壮的和我说数据格式处理不了等。然后改接口数据格式甚至有的改逻辑等。只能说互相理解。但是有时候发生的很频繁也是真的心烦。
经常别人的看法也是,不管是前端还是后端。不非要全栈,但是多少也要懂一些对方的技术。不然真的很容易被唬(真人真事,我一个以前的做后端的同事,前端对接口数据有意见的时候大多数都是一句你这样要求java实现不了。。。。神踏马实现不了啊,然后那个前端经常被唬我觉得)。
不过随着开发我也确实发现接口的定义其实真的挺不好设计的。就前几天的个接口。本来是个添加配置接口,但是最开始的需求文档只有两个字段。我出于嫌麻烦,所以直接决定这两个字段分别以参数的形式传过来。正常来讲这么设计没啥大问题吧?然后随着开发,需求今天说应该可以传个logo,明天说应该加个标记,过不长时间又说这里有个类别比较适合筛选。。因为是自己公司项目,所以都是想到哪做到哪。不说我数据库一个字段一个字段的加。实体一遍一遍的改。单说这个接口我都改了一次又一次。这也就够糟心的了。最后的最后参数变成一大串以后,前端小哥说我这样也太麻烦了,咋不用对象包装。。ex?我特么要是早知道这样哪怕脑袋进了水也不会这样设计啊!!!
还有常常出问题的就是统计报表这一块了。毕竟功能不同,各种各样的统计 ,柱状饼状曲线,二维三维甚至有的点进去还可以放大成4维。。反正现在我几乎统计接口的数据定义都是直接交给前端,美名曰你觉得你怎么拿方便怎么定义。我按照你的要求给你。其实是真的无数次定义封装好了前端苦兮兮的说这样的数据形式展示不了给吓怕了。
还有比较想吐槽的一件事就是分布式的接口调用情况。这个是在我去年用cloud的时候发生的事。有时候一个按钮的调用会触发很多事件。最简单的例子:一个订单的签收会触发分佣,触发订单状态的改变,触发商品销量的改变,触发账户的变动,有的还会触发用户积分的变化。用户和商户的等级变动等等(包括但不限于)。而这个绝对不是一个模块可以完成的。账户模块,用户模块,商品模块,订单模块差不多是跑了个遍。feign确实可以解决。但是有些压根不用交互的模块就为了这么一个接口还要来个调用我自己的懒得写。也可能是懒癌晚期。反正我最终的实现是这么一个按钮让前端调用了两个不是三个接口。当然我不是说我的做法值得倡导。我自己都觉得其实是有点问题的。但是!!!但是方便啊。反正说这么多就是想说每一个接口的功能,作用都是由我们定义的。一个项目的交互也几乎是后端主导的。很多时候良好的接口设计确实会让工作更加融洽和方便,反正我的建议就是接口的设计要慎重,而且最好是根据需求和原型图,流程图来做。虽然随着开发接口的添加和修改不可避免。但是最大程度上减少出现还是很有必要的。
剩下参数什么的我也没啥心得,就是按需求设计,能不传不传,密码等加密传。

技术选型+基本架构

数据库好了,流程图原型图有数了,接口也定义的差不多了,最后还是要落实到代码上。至于技术选型啥的可能因为项目都是非互联网项目,要求也不高,功能也简单,领导有时候还会有要求(比如手头的这个dubbox就是领导指明的)。所以一般不会有太大的选择。

  • 从我入行以来,spring boot就是基石。最开始还用过spring,但是从开始使用spring boot以后就没退回去过。所以项目基石是spring boot雷打不动。
  • orm框架现在主流也就是jpa和mybatis。优缺点都有。甚至二者的底层实现也差别很大。但是有一个不得不说的点:在基本的使用上来说对调用者而言二者没有多大差别。jpa有spring的封装,mybatis有mybatis plus的封装。现在基本都是自动生成实体和dao层。然后基本的crud都由框架封装好了
    mybatis plus的条件构造器。
    反正我觉得对于我使用来说是差不多的。导包。生成entity和dao。然后就是调用。两者我都用过,最近用mp比较多。性能方面简单的操作根本看不出差别。
    至于双方最主要的两个差别:复杂查询和改动的灵活性来说,代码中真的没啥区别了。所以我一般都是随缘选择。mybatis的几率高一些。因为我手头有一套mybatis plus 的项目架子。。
  • 微服务框架
    额,其实我之前在哪里听到过一句话:市场上百分之九十的微服务项目都是闲的。虽然这么说比较偏激片面。但是有时候确实是这样。我经常拿上一家公司举例子,一个还没做起来的项目老板整天考虑的都是分库分表集群微服务分布式。。讲真是有点杞人忧天了吧。
    正常来讲现在的服务器稍微好点的维持一个项目是够用了吧。好一点的单体服务器可以做到10w并发。说实话现在市场上有多少软件能达到这个量的?所以微服务分布式什么的,反正用了就用了,老板愿意花大成本投入我们做的就当学习了吧。
    现在主流的也是我用过的微服务框架cloud,dubbo(现在用过的dubbox是dubbo之上的一层封装,本质还是dubbo)。两者怎么说的,cloud的话我觉得spring对其的整合很好,无论是注册中心还是网关还有服务调用熔断啥的。学起来上手比较快,但是遇到问题解决问题的话要么靠百度要么靠运气。。现在对当时开发过程中的一些灵异问题我也是一头雾水。比如时有时无的报错到现在我也不知道是网的问题还是连接的问题。但是可能是我这种菜鸟才这样,反正我对cloud整体的印象就是上手简单精通难。而dubbo的自由度高了很多,就是一个rpc远程调用。剩下的想要什么功能自己添加(有的是有现成的包的)。不过我只用过那个监听。反正整体感觉二者的简单使用都可以是配置文件配置自己名字和注册中心。然后不管是服务调用还是注册都可以用注解的方式实现。剩下别的功能自己探索吧。因为我这个项目就是要用dubbox所以才简单的说了几句。
  • 数据库细节
    开发以来只用过mysql和sqlserver。所以没啥发言权。传说中的土豪专用oracle只听说过而已。剩下一些别的也没真正用过。反正我个人可以选择就毫无疑问mysql 5.多。但是甲方指定的话别的应该也都可以对付用。毕竟jdbc支持蛮多数据库的。然后基本使用上都是主备两个库。虽然至今也没遇到过宕机啥的,不过就是一个习惯嘛。这个不是很重要。
    至于分库分表啥的我反正也没接触过超过十万的数据。所以弄过分库分表也没啥实际的体会。只能说简单的分库分表,一些常用的分的规则,什么物理表逻辑表的定义是能明白。但是真说实用性也不见得有什么。
  • 常用工具+第三方工具
    其实这个真的是个人积累了,没法细说,比如说定时器用quartz,代码引入lombok依赖,还有json工具包啥的。这些都是便于开发的东西。有了简化代码没有也能实现。随着工作多看看别人的代码或者项目源码总能学到什么的。
    至于第三方工具:阿里的各种服务(短信,oss,身份证识别等等),发送邮箱验证码的封装,微信/支付宝授权支付,极光推送的app推送等等,几乎在理完流程以后这种需要调用第三方的都会心里有数了。而且这些工具类都是做的贼简单,去看看官网几乎都有现成的代码。所以也没必要多说了。

话题转回来,我这个项目的技术选型如下:
dubbo+zookeeper + mysql + spring boot + mybatis plus + swagger。
现在还差一个网关,zuul是用过的,但是查了好久资料都说zuul性能堪忧,soul倒是叫好一片,所以这个网关暂时待定。大概的筹划就是这样。

项目框架

下面是我初步定下的项目大的框架,只用了user和order做例子。简单说就是按照模块分。每个模块又分为三个项目:接口,实现,和调用。



注意这里在api中有个Dto。这个也是问了一些人,看了一些资料后才定下这样做的。
网上也有一种做法是所有的实体和dao做成公共引用。但是这样首先肯定是不合理的。毕竟比如api应该只是干干净净的接口,但是还要引用那些乱七八糟的?其次有个朋友说这样也正好违背了解耦,分模块的概念。但是有时候参数是实体对象的话,api模块和web模块要怎么接收呢?
之前我还灵机一动打算所有参数都map。。然后群里一提出来就被骂了,哈哈。反正是这样会出现魔法值,一点都不合适。
最终决定稍微麻烦点,再封装一个对外的Dto。首先这个也是符合表中数据私有不直接对外的。其次这样一层封装也可以使得数据更加有用(好多对前端没意义的字段可以直接不传了)。其实这种模式早就有,不过以前因为嫌麻烦所以从来都是实体直接对外。这次决定符合规范一点,entity是entity,dto是dto。

到这为止,所有项目的准备工作算是做完了。剩下的就是真正的按照接口文档把接口一个个实现了。肯定实现过程中会有改动。不过只要大方向没问题剩下的改动应该都不大。因为代码的实现也是一个长时间的过程。如果在项目中遇到什么值得记录的事情我会记下来的。本篇文章其实就是一个思路的整理和个人风格比较明显的记录。
如果本文稍微帮到你了记得点个喜欢点个关注,另外也祝大家工作顺顺利利!java技术交流群:130031711欢迎各位萌新大佬踊跃加入。群里好多学习资料呦~

举报

相关推荐

0 条评论