什么是重构?

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

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

重构的分类:

  • 代码重构

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

  之前我们在有次讨论的时候,一个童鞋说:“我们现在的程序设计都被框架封装了,设计模式基本是用不到的。”这个说法我不太同意。因为我们现在也在进行代码重构,抛去设计不谈,但从代码风格上,最令人吐槽的是里面充斥着大量的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.简单明了

 

重构的注意事项:

  • 避免盲目重构

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

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

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

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

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

  

总结与思考:

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

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

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

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

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

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

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

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

 

跑题时间:

郁金香  

  桌上的混合花束,和同事谈事情的时候无意看了一眼,一支郁金香脑袋耷拉下来。原来这一支插入水中的比较浅,它根部的水已经蒸发掉了。赶紧给添了水,并给这支郁金香摆了个造型支在旁边的康乃馨上。第二天,这支郁金香又硬挺起来,而且它的花茎还保持着我之前摆的造型,宛然一件艺术品。原来在挫折下可以变得更完美的,不只是人类,也不只是内心。

樱花

  4月是樱花的季节。记得日本出差的时候,签证最多只能停留3个月。12月底去的,赶上了日本的成人礼,18岁的姑娘们个个穿着和服赶往庙堂,一片美人海;赶上了情人节,夜晚小树林里、公园里好多哭哭啼啼的女孩子;却在只剩下几天就樱花祭的时候回国了。所以看到樱花,心里的感觉总不一样。

  带着大小情人去公园,看到樱花。想起新海诚《樱花抄》里明里看到樱花时的话:“像雪一样。”只是樱花花瓣落于掌心,不会像雪一样融化。而那年春夏秋冬寻寻觅觅想要在人群中看到的那个人、那些曾经拼命想要忘却的记忆,竟然像落于掌心的雪花一样,不见了

蝴蝶兰

  一年四季,前台上总放着一盆蝴蝶兰。我仔细观察过,不是塑料花。室内常见的盆栽,自然条件下本来是开花的,养在花盆里却成了常绿无花的灌木。常说的难以办到的事情之一就有:“铁树开花。”巴西铁其实却是可以开花的,只是条件苛刻。而蝴蝶兰却总是给人最美的样子,像是痴痴地等待着一个人。

  我用一生等你,你不来我不老。

 

招贤纳士:

    美团点评核心交易招收实习生,方向:JAVA开发。要求:19年毕业研究生、985院校优先。有意向请与关注我的公众号:编程一生,并留言。

 为什么要持续重构 随笔

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄