为什么要持续重构

简介: 什么是重构?重构是在不改变软件可观察行为的前提下改善其内部结构。---Martin Fowler通俗说法:看起来没做啥调整,让系统继续更好的满足客户需求。同时,希望重构完成后,这个系统能够多蹦跶几年。

什么是重构?


  • 重构是在不改变软件可观察行为的前提下改善其内部结构。---Martin Fowler
  • 通俗说法:看起来没做啥调整,让系统继续更好的满足客户需求。同时,希望重构完成后,这个系统能够多蹦跶几年。

 


重构的分类:


  • 代码重构


  如果想了解代码方面的重构主要有哪些方法,可以参考《重构:改善既有代码的设计》、《重构与模式》。


  之前我们在有次讨论的时候,一个童鞋说:“我们现在的程序设计都被框架封装了,设计模式基本是用不到的。”这个说法我不太同意。因为我们现在也在进行代码重构,抛去设计不谈,但从代码风格上,最令人吐槽的是里面充斥着大量的if和else。刚毕业的童鞋可以觉得很正常。但是稍有经验的人就知道这些逻辑计算应该用策略来代替。设计模式是从细节代码到设计架构处处充斥着的一门设计美学,任何工程师都需要掌握和学以致用。


  • 架构重构


  如果想了解架构方面的重构主要有哪些方法,可以参考《软件设计重构》。下面列了一些架构重构方面的主要考虑点,并对其中一点做了说明。


  1>可扩展和负载均衡策略

  2>数据库的读写分离和主从切换

  3>按需扩容

  4>两地三中心,机房故障也能稳定的提供服务

  5>持续的容量规划


  每个阶段都有自己的业务目标。订单量会对系统容量有新的要求。针对业务目标做评估,对组件做评估,看当前支撑的量是多少,找到其中的瓶颈点做架构升级。应该有1.5倍到两倍的冗余。把握节奏,太早会影响需求的迭代速度,运维成本高。太晚会不足以支持单量。


技术方案长期规划,逐步实施。持续重构,重构在每个阶段都要有人力。


  6>持续的性能优化

  7>性能影响用户的留存率、成本

  8>单机容量低、响应慢 

 

重构的目标:


  • 最终目标:更好的承载业务


  • 具体目标有:改进设计、模型规范、重建生命周期、增大负载能力、提高响应速度、抽象、解耦、无法维护、扩容、业务复杂度、降级开发成本、容易理解、技术栈革新

 

重构面临的问题:


  • 新的系统就不会再有问题了么?
  • 再过几年,新系统也会变成老系统
  • 一个正在运行的系统,如何新老系统平滑迁移?
  • 日常需求不停顿,还要花费大量精力重新设计编码
  • 之前踩过的坑如果没有很好地沉淀,可能会重新入坑


  既然重构面临这么多问题,到底要不要重构?那就问自己愿不愿意为重构负起责任,坚持到底,并承担后果。

 

为什么要重构?


  一般说需要重构了,都会是因为面临着一些问题。近期问题如:不能支持业务、故障、响应不满足需求、单点无法扩容。长期问题如:维护成本大、扩容成本大、有明显风险、不支持业务扩展。


  我们的代码迫切的需要重构。我曾经为了申请重构资源,做了很多工作想让领导认识到我们重构的必要性。尝试着列举不重构的话,TOP3无法解决的问题:


  1.我们是一个平台系统,当初的设计却是为了其中一个业务研发的,功能都是定制化的

  2.在不合理的逻辑上叠加需求


  3.数据模型不能覆盖目前的需求


  不重构很痛,但总感觉没有说到痛点。后来我们领导说:“重构的目的是为了甩掉历史包袱。”听着更接近本质一点了,但是总感觉还是缺少什么。


  后来我仔细想了一下。当初必须要重构。因为不重构一改就会出问题。当初资源申请困难是因为我一直都没解释清楚为什么一改就出问题。因为按照正常的理解:改出来问题是能力的问题,对业务没有很好的把控,对代码没有深入的研究。而实际上重构是因为”坏味道“使得架构和代码本身已经无法阐述它的行为。再通俗点说就是:现有架构和代码,与目前承担的事情不是一个东西。

 

为什么要持续重构?


  • 从本质上,重构就是在代码写好之后改进它的设计。


  • 如果你发现自己需要为程序添加一个特性,而代码结构使你无法很方便地达成目的,那就先重构那个程序,使特性的添加比较容易进行,然后再添加特性。


  • 重构改进软件设计,因为代码结构的流失是累积性的。


  • 重构使软件更容易理解


  • 重构帮助找到bug


  • 重构提高编程速度


  对我们组来说,为什么要持续重构?


  因为持续重构的代码是确保代码长期没有人动,一动就出问题的有效手动。

 

何时重构?


  • 三次法则:事不过三,三则重构。


  • 添加功能时重构


  • 修补错误时重构


  • 复审代码时重构

 

重构和性能优化


  • 重构是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。它提供了一种更高效且受控的代码整理技术。


  • 和重构一样,性能优化通常不会改变组件的行为(除了执行速度),只会改变其内部结构。但是两者出发点不同:性能优化往往使代码较难理解,但为了得到所需的性能不得不那么做。

 

”两顶帽子“如何权衡 


  在开发过程中,通常会遇到两顶帽子。一顶是需求的帽子,一顶是重构的帽子。囚徒困境,如何抉择?


  我刚接手交易的时候,对此也很迷惑,所以特地去了解了一下交易的前世今生。了解之前的交易负责人的关注点。有的疲于应付询问和问题;有的关注需求;重构是解决业务支撑开发量大的有力武器。但是需求来了,怎么办?


   权衡的时候,重要紧急、重要不紧急、紧急不重要、不重要不紧急的四象限理论怎么发挥作用?都紧急的时候怎么按照重要度来进行排序。


  回答这个问题就要先弄清楚交易最重要的是什么。交易的核心是稳定。如果重构是维持稳定的必要条件,而我们需要一个重做级别的重构,需要大量的时间。那么这时就需要保证重构和需求至少1:1的投入。

 

重构的原则


  1.测试优先原则


    TDD(Test-Driven Development):测试驱动开发


  2.OCP原则


    Open For Extension:开放封闭原则


  3.小步快跑原则


    大布局、小迭代


    进化式设计和增量开发


      避免过度设计,对于未来的变化,既不要考虑的太多,也不能一点都不考虑

      代码满足当前需求,并留有可扩展余地


  4.数据一致性原则


      分库分表(横向、纵向)

      字段合并、冗余

      索引优化、数据缓存

 

重构设计方案选用


技术方案没有好坏,只有合适不合适。合适的方案用到合适的系统。判断合适主要考虑的方面:


1.业务契合度

2.覆盖面全不全

3.扩展性

4.人力投入成本

5.系统稳定性

6.安全

7.简单明了

 

重构的注意事项:


  • 避免盲目重构


  要重构,上面我的内容我自己认为都是需要想清楚的。另外还有一点,需要对重构系统进行一个生命周期预估,包括:


  • 未来需求预判
  • 模块划分拆解
  • 总结历史问题
  • 隐性及显性需求


  我在知乎上看到说怎么判断隐性需求:隐性需求就是大家都觉得很不爽,但是又说不出个所以然。显性需求和隐性需求实际上没区别,视力不同的人看到不同的世界,洞察力不同的人看到不同的需求。


  • 割接(新旧系统替换、迁移)实测演练


  这块着重说一下,交易重构的割接采用的是留壳抠瓤的方式。就是对外接口和暴露方式不变,内部逐渐灰度用重构后的系统来替换新系统。

 

总结与思考:


  以前上学的时候最不喜欢遇到主观题。因为一个试卷上有主观题,就基本上意味着得不了满分。 如今工作中,发现自己做的都是主观题。别人给自己打分,自己给别人打分。说好的标准可能到时候会发现难以实施。说好的加分项,自己也做了很大努力的,结果真正打分的时候,也只能呵呵了。但是通常面对结果,我会对自己说:“我会有一分钟的不开心,但是我服。”


  因为打分的人总有自己的思考过程,得不了满分总意味自己有改进的地方。牺牲两周的午饭时间排练的街舞,得了第一名,也就得了一副蓝牙耳机。结果其实没那么重要,只是过程很开心而已。但是经验与教训的区别:经验给出了一条思路,教训却给了很多条。


  我之前一个同事,自己创业失败去了我之前工作过的一家公司。后来在美团刚起步的时候加入了美团。做好了之后,如今又去了另外一家刚起步但是很有前景的公司。


  我还认识一些人。他们很早买了房子。房价涨了,他们觉得赚了。又继续买了其他的房子。同样,价值都在增长。


  这些都是成功的经验得以复制的例子。


  教训的例子却不太好举。因为一旦成为教训,做出的思考很多,采取的改进往往也不是单方面的,得到的提高也往往是综合的。


  如今,我不再怕主观题。对别人给我打得分,我会给自己一个实质性的收获。对我给别人打得分,我也会给别人一个满意的成长。在公司里能够得到的最大财富就是自身的成长改变,所以感激每一件能让自己反思自身的事情和经历。


  就像我常说的:人生就是一场游戏,关键是经验值。

相关文章
|
存储 SQL 关系型数据库
如何设计可落地的重构技术方案——理论篇
如何设计可落地的重构技术方案——理论篇
306 0
|
3月前
|
敏捷开发
敏捷开发:拥抱变化,快速迭代
在软件开发领域,敏捷开发已成为应对快速变化、提升交付效率的有效方法。它强调团队协作、客户反馈和灵活应变,核心价值观包括个体互动优先于流程工具、可工作软件优先于详尽文档、客户合作优先于合同谈判、响应变化优先于遵循计划。敏捷开发通过跨功能团队、短周期迭代、持续改进和客户紧密合作等实践,实现高效开发和创新。虽然面临抵抗变化、管理期望等挑战,但敏捷思维能显著提升团队表现和产品品质。
|
7月前
|
设计模式 供应链 安全
如何在短频快的节奏中做好技术?业务开发必会的架构思维
本文提供一种业务架构设计模式:从业务&技术两个角度提炼出一个基础思维框架,供业务线开发同学参考。
如何在短频快的节奏中做好技术?业务开发必会的架构思维
|
7月前
|
SQL 运维 监控
老系统重构系列--稳定性摸排灵魂三问
该文主要讨论了老系统改造的过程和方法,特别是针对版权资产管理-财资系统的重构。作者强调了系统稳定性的重要性,并分享了他们团队在重构过程中采取的策略。他们通过确定目标、制定方法论和实施步骤来确保问题的全面摸排,包括核心链路图、流程时序图和问题路由图的绘制,以识别可能的问题和需要加强监控的部分。此外,文章还提到了数据对账监控和系统级统一监控的重要性,以及技术改造和预案的制定。作者提供了相关文章链接以供进一步阅读,并分享了他们在摸排和整改过程中的实际成果。
112 0
|
存储 NoSQL 关系型数据库
重构之道:揭秘大规模系统重构的经验与挑战
重构之道:揭秘大规模系统重构的经验与挑战
996 2
|
开发者
工作一年,我重新理解了《重构》
重构是一种在不改变代码本身执行效果的前提下,让代码变得更加整洁易懂的方式。代码不仅要让机器能够实现预期的处理逻辑,更要能够面向开发人员简洁易懂,便于后期维护升级。
379 5
|
算法 安全 Java
重构--必经之路?
简要讲述代码重构是什么?为什么要进行代码重构?如何写出干净整洁的代码?
|
测试技术 程序员
代码重构的力量:如何衡量重构成功
许多工程团队都在努力衡量他们重构工作的有效性。让我们看一下可以帮助您衡量重构成功的 5 个指标。 代码重构为开发人员提供了急需的精神休息,我认为许多开发人员都可以与此相关。整天编写代码要求很高,尤其是在您每天创建新功能的情况下。这是一项繁重的工作,开发人员通常需要一些空间来思考代码库的整体组织并回顾可以改进的地方
174 0
|
设计模式 JSON 测试技术
项目重构演进之路
项目重构演进之路
741 0