• 前端开发要从未来着眼做开发


    注:下面内容没有任何代码的解决方案,纯是这些年做开发的一些总结吧。想看理论知识请看理论

    为什么要写这篇文章

    最近公司开启了一段忙碌的时期,我接手了一个最开始由之前其他同事的代码,先说一下项目内容吧。项目很简单,包含:

    1. 可切换tab的列表页面
    2. 稍微复杂(说是复杂,其实是不过是条件比较多)的检索的页面
    3. 一个web-view的详情页
    4. 一个下载文件的页面

    说是四个页面,其实说白了就是查询、详情的页面,我预计也就是一个人三天的工作量(从我角度去看),这份代码最开始由公司三个新人去写的,写的期间是这样的一个状态:

    我预估为:3个新人三天,一人一个页面不算多吧(下载文件没啥东西,就一个loading,调用wxapi)

    开始还算顺利,前两天基本的架子都已经出来了,基本的查看、查询也有了。这时候我手里还有很多其他更重要的事情,所以没有去深入看他们代码。只是在页面点点,大致是可以通顺的。就在这个时候,客户提了两点问题:

    1. 检索的参数经常出问题,多点击几次查询就会出问题
    2. 检索的全选无法取消

    噩梦就此开始,当开发到第四天时候,我去询问了进度,说是差不多了。当晚上我腾出时间去验收的时候,我发现会有很多小瑕疵,比如传参数时候经常会出现一个空比如多选我们是按照逗号分割,经常会出现,,,,这样的value。比如全选之后,点击其他的checkbox并没有取消全选的状态。诸如此类的问题。这时候我意识到可能会有问题。细致的去看了一下问题

    多选项的数据源

    image.png

    选中条件时候的赋值操作(把后台参数直接字符串拼接的方式)

    image.png

    详情页面获取参数

    image.png

    详情页面赋值

    image.png

    这样的代码数不胜数,因为有些地方是属于机密部分,外加篇幅原因,本文不予展示,总结问题为以下几点:

    1. 晦涩难懂的变量名
    2. 成排/嵌套的if/else
    3. 数据没有解析为可理解的结构
    4. 查询参数字符串拼接,造成发散式的变化
    5. 数据源在js文件内遍地开花
    6. 极度庞大的单函数
    7. 大片的重复轮子

    我可以负责任的告诉大家,这只是冰山一角的问题。造成结果是什么?从测试开始,提出了近50条bug,因为时间紧,老板最开始要求五天内完成开始我的做法是帮助他们去解决各种bug。

    直到最后,每天白天我做我的工作,晚上我问进度的话还是前一天那些,他们根本梳理不清了自己的代码和逻辑。最终是被老板一顿凶,项目开发了大概三周还很多bug(在第十天时候,我感觉他们可能确实困难了,长痛不如短痛,期间安排了两个小组长重构过一波)

    小组长跟我说的最多的就是:老大,这个bug我解决不了。小组长重构时候,我给他们简单讲了一下每个页面应该怎么做,大致应该怎么做。但是俩个小组长也被他们带跑偏了,只是改了一部分,代码就变成了新旧混合状态,大部分还是新人写的代码,当时bug都处理了,我想就先这样吧,实在是没那么多时间,等过两天我有时间在处理。

    但是当我到客户现场这几天,随着客户频繁的增加、删除功能,我经常会不知道怎么的就改出问题。而且,简单的 bug 也会浪费的时间极其多(因为就一个变量,我都要看好几遍才敢确定是干嘛的)。终于我加了两个晚上班,对客户提出修改的需求的查询页面、详情页面和下载进行了完整的重构,这才算解决了这个痛点

    作为负责人的我,在这次事故,有不可推卸的责任,也让我对从未来着眼去写代码的理解更深了。先说说我重构的观点:

    1. 对迫切的点、变化的点去做重构
    2. 如果我觉得可以挽救的地方,我会选择小范围、小步子重构,如果实在是无法挽救了,我会吧逻辑梳理清楚、做好backup后,完全的重写

    我都做了什么:

    1. 详情页面

    完整的重写,将其划分为几个主要文件:

    image.png

    ps: 只是最基本的一个模块化开发,没有弄太多花里胡哨,太高级的玩意,在我看来这就够了,其实里面有不少问题,比如:数据啥的和视图都混合在一起、enum/data等文件和main在一起了等等。但是在我看来这就够了,也将这个思路分享给大家,有时候,不要太较真,要结合项目及时间实际情况。

    当然内部的代码处于保密原因,不予以展示,具体重构手法可以参考重构读书笔记

    2. 检索页面

    局部重构,重构点包含:

    • 2.1. 不对结构变动,新增enum,把内部的一些写死的值进行抽取

    • 2.2 对之前检索错误的方案进行整理和重构,让他们在正常操作中都是操作数据,只有点击查询时候才对其进行一个数据解析,解析成后台所需要的样式,以达到操作的解藕,更好的发挥前后端分离带来的乐趣,后面不管改什么bug都可以得心应手,在我看来从未来的角度去写代码的关键原因就在于此。

    **3. 列表页面: **

    局部优化,优化点为:

    列表页面是可以继续使用的,因为从检索页面返回来,他要的本来就是一个json,但是没有一个统一的检索位置,所以我选择对其进行抽取统一即可,不动页面而优化我想要的样子

    • 3.1. 函数提炼,复用

    • 3.2. 函数改名,提高语义化。

    上面改动这块写的比较乱,是因为时间太久了,最近写一点就去忙了,断断续续了四五次了,先放一放,等我有思绪后再整理一下,回归今天主体:从未来着眼去写代码,换句话说就是:前瞻性开发。

    理论

    先来看一下百度词条的解释

    前瞻性指往远看、往前看的特性,与预见性的意思相近。就是要有长远的眼光,能够想到还未发生的而又有可能发生的事情。

    其实,看这里我们就可以明白前瞻性开发代表的含义,但是现实开发中又掺杂了很多“无奈”,那我们应该怎么在现实和理想中权衡,得到一个比较平衡的点呢?

    首先我们接到了一个项目或任务时候,我们需要:

    需求是否合理,确定业务需求可行性

    可行才会有向下的可能性,如果不可行则需要重新讨论需求,可能是和用户讨论,也可能是和自己团队进行沟通。

    确定的过程中我们可以借助经验、敲一个简单的 demo 进行试验、从需求出发到实现的过程进行简单的串通

    梳理好业务/需求后,确定是否可以对业务进行简化

    尽可能将功能简化,可以减轻后期浪费大量时间去耽误在无关紧要的点上,亦可以让程序减少一些无关紧要的兼容和处理,相对来说,一份简化的程序,可以让我们比对:大批量的不必要的代码交织的程序维护起来更加简单

    将要实现的功能与开发人员进行碰撞,力求得到一个比较优的解(针对一些特定的需求很难最开始就得到一个最优解,那我们可以退而求其次,求得较优的解)

    注意:简化程序并不意味着减少重要地方的易于扩展的兼容处理。 注意:简化程序并不意味着减少重要地方的易于扩展的兼容处理。

    了解任务的轻重缓急。

    将拿到的需求、业务进行划分,哪些部分是不紧急的,哪些部分是必须要尽快的,如果可以最好能了解到每个部分的大概节点。这方便我们接下来制定计划

    1. 自己会不会再次遇到在这样的任务?
    2. 有哪些是你可以借助已有的模块/方法的?
    3. 针对一些特殊的任务/功能,你需要如何应对?

    制定计划表

    到这里开始体现前面所做的努力。计划表这种东西,用多了就会发现他的妙哉,能够帮我们理清业务整体进度处理节点、让我们一直能够胸有成竹。

    针对计划表,结合之前我所说的三个步骤,我觉得可以有如下几点建议:

    1. 删除不必要的任务

    对于没有必要做的部分,就干脆一点不要写在表上,以免浪费你的时间,还可能让你因为开发困难徒增羞愧之心。如果确实是不必要的部分,你没有必要花费精力和时间。因此,在列计划表时,不要拖泥带水,要干脆利落。

    1. 将要做的列明

      将每天要做的任务“要做”的列明、列细致,完成一项任务并核对关键点后就从“要做”的表内划掉。随身携带这份计划表,确保完成表上的任,ps: 如果做了很长时间都无法完成某一项任务,那你得重新审视计划表所列的处理时间和任务难度是否存在不匹配了

    2. 审视一下我们项目内是否有可以重复使用的地方

      这个可以是个人中心这一个功能、也可以是 downloadFile 这么一个方法,避免我们重复造轮子,浪费宝贵的时间

    3. 表列好后,客观的审视一下自己是否可以把任务处理更好,有条件的情况下可以求教一下比我们厉害的人,让厉害的人帮我们完善我们的不足

    4. 预测可能出现的问题,并将其扼杀在摇篮里。

    我们梳理好表内容后,细想整个程序,发现并消除问题出现的可能性。保持谨慎,同时做好问题出现后的应对计划。

    ps:这里可能是 3、4、5不断重复打磨这份计划

    动手

    1. 在我们空闲的时期,将不紧急,且常规的任务做在前头。

    在我们空闲的时期,我们不要荒废掉,去把一些不需要前置条件的任务做完,比如代码审查、样式兼容、未来任务铺垫等任务

    当紧急任务来临时,这些任务都应该是完成了的,无需再占用你宝贵的时间了,并且时间紧急时可以减少其他问题的干扰

    1. 将我们的代码进行前瞻性思考

    我们在开发中,需要将当前开发和下一步的开发、未来的维护进行结合,对我们的代码进行提取、封装,这是我们针对模块级别的“基础建设”,包含组件、通用方法、基础类等,在构建“基础建设”过程中,如果我们是一个大项目的一个小模块,我们还需要与整体项目进行关联,判定哪一块需要我们封装到全局,哪一块我们封装到模块,这很需要一个程序员对自己项目的整体把握程度,如果不够了解整体项目,就无法判断全局还是模块级。

    开发过程中,应当把握好设计模式与需求、维护的实现难度进行权衡,即不要从上到下文言文似的开发(指的是晦涩难懂的代码或是别人很难维护、扩展的代码),也不要为了使用设计模式而使用设计模式。

    在平时项目开发中,其实更多时候我们不会使用设计模式,设计模式的目的是提供可拓展性和可维护性,但是我们开发的项目本身,大部分都是固定写死的,逻辑单一,所以,平时开发中用到设计模式的地方很少,但是框架就不同的了,框架必须适应不同的项目,具备高弹性和拓展性。

    框架要能适应各种不同的环境,所以,设计模式在框架设计中处处可见,这些框架就需要满足不同的需求,使用不同的配置插件,定制化。

    我们项目中的登录,分为不同场景下可能会使用 base64、有些场景会使用 MD5、还有一些是 rsa 非对称加密、甚至有的需要插入 key,这里就必须使用策略模式,虽然登录可以算是业务,但是更多时候,我们登录不需要修改,而当我们更换场景时候,我们可能就需要更换不同的加密方式,就我们场景来说,这又是一个框架级。

    并不是说业务中我们就不需要使用设计模式了。比如我们模块开发时候,经常需要传递消息,那我们就需要使用发布订阅模式;

    再比如说,我们可能为了消除 if 的堆砌带来的阅读困难,经常会选择用策略模式去实现;

    或是我们为了解决大量对象,造成很大的内存开销,可能会使用享元模式;

    以及在我们很难去深入理解项目代码时候,又要处理一些问题时候所选择的亡羊补牢方式:适配器模式

    等等场景还是有很多的。实际开发中还是要根据需要来进行选择。

    1. 开发过程中,我们就应该边写边思考。
    • 开发中应该尽可能选择较为优异的方案去编写,尽量不要将就。

    • 开发时候就要不断的对已有部分进行优化,可以随手就可以优化的就要及早处理,比如:

      1、不好的命名,a 方案比 b 方案少写两个字母,比如命名上,有的人会选择使用 ite、ind来代替具体的含义,首先他写的这个很难看,意思也不明确,item/index我觉得在某些场景下还有点用,但我更建议你把他命名为符合他的用武之地的名字

      2、把一些重要的 ATTR 提到前面,让未来修改人(也可能是你自己),能够率先看到控制元素的核心信息,诸如:v-if、v-show、ref等

      3、函数开发中要尽量简化

      SRP(单一职责)原则几乎是所有开发者都必须要懂得的一个原则,并要坚决地将其贯彻到底。

    开发完毕后,检查我们的代码功能是否有所遗漏、功能是否存在 bug

    在这个时候,我们就要化身测试,对我们的程序功能点进行复盘、程序进行测试(需要考虑实际业务场景,比如是否有高峰、数据异常操作处理)

    待测试完毕后,我们有时间的话可以回归一下代码,随着我们第二次进行复盘,我们对程序的使用和使用的问题可能会有新的启发,这个时候,我们可以复盘一下代码,对代码进行优化、增加安全措施、简化操作方式

    评价你的工作流程和步骤。其中哪些有效,哪些无效?可以在笔记本上写上改进的方法,下次试试改进后的方式。摈弃无用的,改进有瑕疵的流程和步骤。

    这里可以分为两个方向,一个方向是自己站在客观的角度上

    • 这次自己疏忽了哪些地方导致开发耽误时间过多、有哪些地方是可以有改进的,下次可以更快的方案,等到下一次去尝试

    另一个方向是去询问别人的意见和建议

    • 多听别人的提议,不一定是比你强的程序员,也可以是比你弱的程序员甚至是其他岗位的意见(比如产品经理、测试),这样也许可以获得不同的灵感,让你能够快速成长。

    以上我觉得前瞻性开发的开发过程已经讲述完毕,但,我觉得前瞻性思维不止体现在任务开发中,也体现在日常的自我修养。

    日常中培养前瞻性

    培养解决问题的思维方式,不要让自己一味地沉浸在问题里。

    1. 针对问题下个定义(具体是什么问题?)
    2. 要解决问题,需要做哪些事情,而你又应该怎么做。
    3. 着手解决问题。

    多加强对业务的理解

    很多前端,最不关心的就是业务,认为业务是业务,技术是技术,技术实现完业务需求就OK了,不需要深入了解业务。

    但,代码逻辑本来就是业务逻辑的反映,如果连业务都理解的不清楚,稀里糊涂地写完了代码后,发现业务逻辑和代码逻辑根本就不匹配,就傻眼了。

    在深刻理解业务的前提下,通过技术手段促进业务的尝试成功率能显著提高

    前端就像一个桥梁一样,需要贯穿业务、设计、后端、用户,一个不懂业务的前端,是没什么晋升的通道的,在前端遍地走的行情下,只有技术不懂贯通的前端,是很容易找到替代品的。

    丰富自己的技能

    • 技能的宽度

    俗话说技多不压身,及时的让自己了解行业内最新动向,以及一些成名已久的框架,能够让自己在接到任务时,快速确定自己的解决方案

    • 技能的深度

      俗话说(哪这么多俗话),一门精门门通,开发程序亦如此,当你把某一门技术/框架玩的很溜,你去上手其他一些新的技术也会很容易上手,关键在于要多去学习框架的核心部分,而不是去学习语法,学习语法终究会被时间的车轮碾压的粉碎

    将常规工作分配出去

    正如电脑可以自行处理各种数据一样,将程式化的任务分配出去,可以节省你的时间。例如,你是单位的领导,你可以将自己手头的工作分配给团队内最擅长的人做,这样可以最大限度地利用时间,对他们进行代码的一个审查、需求完成的一个审查。形成“每人做擅长之事”的机制,从而减少问题的出现,而你更多是去从中完善

    多看书

    多看一些对自己“有用”的书,不要都用了 vue 开发了三年了,还去看语法的书籍,那也太不上心了。

    我觉得一个前端应该更多去看产品设计思维、提高代码质量、用户沟通、技术思维、框架代码分析等对自己开发思想有用的书,站在巨人的肩膀上才能看得更远嘛。当然也要根据自己的实际情况,别来个还没用过 react 就去看react 底层代码。

    百度/Google能力

    没错,你没看错,一个优秀的前端应该懂得怎么去运用百度/Google 的能力(也包括别的渠道:比如大佬群、相关isuse)。会用渠道的人,基本很少能遇到解决不了的问题

    在这点上,我们要不耻下问,但要有条理、有关键点。即不要就截图一个 v-for="(item, index) in list" 然后就问为什么我这个什么都没渲染出来。

    针对大佬群、isuse,我提炼了一下几条,大家可以参考一下

    1. 问题是什么?
    2. 问题产生的环境和背景
    3. 遇到的问题现象描述
    4. 自己对问题的思考过程与看法(也可以是自己尝试过的方法)
    5. 必要的关键源代码
    6. 如果是有必要最好能够 准备好最小且可复现问题的 demo

    针对搜索引擎,大家可以参考如下:

    1. 搜索引擎查询不同于上面的,更多都是靠搜索引擎精确地匹配,可以结合上面的isuse 的几个建议,进行提炼关键词。
    2. 直接搜索关键报错内容(一般基本都是xxxError后面的一句)
    3. 有一些问题没有报错,这时候可以在确定报错位置的代码后(这个都是靠 debugger 基本),百度搜索这个 api 报错
    4. 根据查询的内容,进一步推断自己的问题所在可能,在这基础上,结合之前的内容,进行延伸查询,一直到问题确定
    5. 有时候东西太多可以借助《ctrl+f》进行过滤关键的字段。也可以是借助插件

    好了,暂时就先做一个结尾吧。在从未来着眼做开发(或者叫做从维护着眼做开发)这条道路上,前端还有很长的路要走。希望本文对你有所帮助吧

  • 相关阅读:
    linux下操作mysql
    数据指标系列:电商数据分析指标体系总结V1.0
    技巧系列:电脑微信多开方法
    Excel可视化:柱状图与柱状对比图
    数据指标系列:销售数据分析指标体系总结V1.0
    Excel:数据分析excel函数总结
    一种很简单的按键判断方法
    开始VC
    altium designer 画板子的一些收获
    stm32通用定时器
  • 原文地址:https://www.cnblogs.com/jinzhenzong/p/15797982.html
Copyright © 2020-2023  润新知