设计过度有时比设计不足更可怕
相比设计不足,其实我更怕过度设计!
从一次面试看架构技术选型
前段时间面试了一个Java程序员,其中有一个项目的技术选型采用的是Springboot+SpringCloud+Mybatis、Redis+MongoDB+MySQL、FastDFS的技术栈组合。因为我对他所在的公司稍微了解,感觉没有必要选择微服务架构,就问了他们在项目的过程中使用这套技术体系有没有遇到什么问题以及为什么选择这套技术体系。
他们是一个只有七八人的开发团队,能参与到这个项目的人员肯定更少,整个系统却拆分了7个微服务,开发的速度慢,后期运维的复杂度高,给客户实施的成本也很高,现在想想的确是存在过度设计,真的有点得不偿失。
微服务虽然有众多优点,但也不是所有项目都适合用微服务架构,从上图中可以看到,在刚开始的阶段,使用微服务架构模式开发应用的效率明显低于单体架构。但是随着应用规模的增大,基于微服务架构模式的开发效率将明显上升,而基于单体架构模式开发的效率将逐步下降。对于小团队来说,前期的效率以及能生存是至关重要的,贸然的使用微服务架构就意味着前期要为未来买单,但是未来发展的规模,以及到达交叉点的进程都是很难判断的。
技术选型错误的惯性思维
当程序员成长为技术负责人或者架构师后,经常要面临着技术的选型,仔细想想,我们是不是会犯以下惯性思维:
“因为大家都在用它啊”,比如我面试的这个程序员的团队之所以选择这个技术,正是因为它比较流行,如果我们不用,我们可能就落伍了。
“因为我没有用过这项技术,我感兴趣,我想学一下”,其实这也无可厚非,对于新技术的拥抱是每个程序员都要保持的。但当你不只是代表你自己,而是代表团队的时候,仅仅这么想也是不对的,你要站在团队的角度综合判断,合适的才是最好的。
“因为我只知道它啊”,这种情况更多。你为什么选择 C3P0 连接池?因为那时候我不知道还有哪些别的数据库连接池……
技术选型的理性思考
当我们作为单个个体去学习时,我们可以选择那些流行的、有市场前景的、能提升自己能力的技术,但当我们代表团队,代表一个项目去做技术选型的时候,我们更需要理性思考的。
业务需求的考虑
* 短周期项目还是长周期项目
* 对现在的规模是否明确,对未来规模能否准确预测
* 重要的项目(稳定优先)还是不重要的项目(适当激进)
团队自身的考虑
* 复用优先,积累为重,不轻易重复制造轮子
* 先小面积实验,再大面积应用
* 考虑到团队的规模及发展
* 考虑当地的人才储备(当年转型互联网,曾考虑Ruby,最后放弃了,因为在我们这个地方,几乎招不到相关技能的人)
技术本身的考虑
* 技术的匹配度,满足度。技术是为业务服务,不要为了技术而技术
* 该技术在行业的应用程度或者对发展有正确判断
* 技术的选择最好有延续性,便于深度积累
设计过度的表现及危害
程序开发上的设计过度
所有东西都是通用的,过度抽象
有的时候工程师会对此过于着迷。我们会忘记解决商业问题,而是将是将浪费在寻找完美的抽象概念上。容易导致进度被耽误,短时间内未被复用,价值体现延迟严重。
滥用设计模式
每个程序员都要学习设计模式,它的确能帮我们写出更优雅的,更具扩展性,更可靠的代码。但千万不要张口闭口设计模式,不要处处都是设计模式,把原本简单的事情搞复杂。
系统架构的设计过度
过早的拆分
也许你要问上一篇文章《凡架构必拆分,分则有度》中不是说凡架构必拆分吗?但是请你不要忽略了更重要的那句话“分则有度”,这个度不仅仅是指粒度,也包含了时机的把握。一个小系统,何必要拆成微服务,何必要分库分表,何必要分布式!你也许说,未雨绸缪,未来业务大了呢?下棋是走一步看三步没说看十步八步。过早的拆分只是用今天的成本来解决未来的期望,如果业务没做大呢?也许没多久业务就停了呢?提前付出的成本有没有必要呢?
过度的炫技
很多时候,技术人员有炫技的毛病,也不管值不值得用,反正用上了就可以吹牛逼了。连个访问量都没有,堆了一堆的分布式缓存;什么Kafka,MQ,NoSQL,能用的都用上,证明我们技术很牛逼。技术的目的是解决问题,用最低的成本解决问题,绝不是拿来炫耀的。
产品上的设计过度
一口气搞一个大而全的产品
很多时候,我们常常是没有过人的能力却有无人企及的欲望。有些产品人员做产品就是不停的加功能,这个要有,那个要有,还要快、快、快。本来系统就像大海里的冰山,能看到的部分只是冰山一角,很多技术上的东西是隐藏在下方看不到的。而只关注产品功能的大而全的产品,往往就变成了大海的浮冰,好似无根之木,背负着巨大的技术债务,等着后期去偿还。(架构思维的演化思维对应着产品思维的迭代思维,后面的文章再详细介绍)80%的用户只会用到20%的功能,与其一上来横向扩张,不如纵向纵深,好用的产品远胜过可用的产品。
啥都是可配置的
可配置是系统扩展能力的体现,我们看到的市面上大部分的ERP的产品都具有丰富的可配置能力。但可配置也不是万能的,首先灵活的配置需要更高度的抽象,需要考虑更多的场景,对于产品设计、技术开发的要求甚高,当然开发成本也很高。即使考虑的再全面,依然无法预知未来的场景,也无法做到一劳永逸。而且过度的配置,会让功能更加复杂,系统运行效率变低。过分的追求系统的灵活而付出的代价需要权衡。约定大于配置,也许在产品设计上也可以适用。
设计不足可以逐步完善弥补,而过度设计却会产生浪费,会牺牲敏捷,错失机会,付出的代价更大。说白了架构是一种权衡。在运行效率、开发效率、硬件投入、开发进度、稳定性、可扩展性、团队成员素质之间找到一种最佳平衡即可。
从淘宝的发展看系统架构的演化
罗马不是一天建成的,今天的淘宝网也不是一开始就设计出来,通过上图让我们回顾一下淘宝网整个系统架构的演进变迁,去体会架构思维其中一个非常重要的演化思维吧。
架构是设计出来的?还是演化出来的?我个人基于十多年的经验认为,架构既是设计出来的,同时也是演化出来的,对于互联网系统,基本上可以说是三分设计,七分演化,而且是在设计中演化,在演化中设计,一个不断迭代的过程。下图是系统架构发展的历程,从而也能看出系统在不断的业务推进中被推动着向前。
当然一开始的架构设计非常重要,架构一旦确定,它将支撑很长一段时间,好的设计能延长架构的生命周期。同时,优秀的架构师深知,能够不断应对环境变化的系统,才是有生命力的系统,架构的好坏,很大部分取决于它应对变化的灵活性。所以具有演化式思维的架构师,能够在一开始设计时就考虑到后续架构的演化特性,并且将灵活应对变化的能力作为架构设计的主要考量。提前考虑却不过早实施,即避免了设计不足,又不会导致过度设计。
如何避免过度设计
虽然没法完全避免过度设计,但下面几个建议希望对大家有用:
一定记住设计是为了满足需求,不要为了设计而设计;
不要花费太多精力在你觉得一年之内不会提出来的需求上;
如果一个实现能比较容易的改成另一个实现,现在选择容易的一方;
不要花太多时间在设计上,人人都超不出自己的界限;
不要指望一下把所有细节都设计出来,边写边重构是个好习惯;
最重要的一点,架构是不断演化的,根据业务进展不断迭代,不断完善
《程序员的思维修炼》是菜根老谭结合自己的工作经历和对这个岗位发展的认知而专门开辟的一个专栏,旨在分析程序员的职业发展的过程中我们应该锻炼哪些思维意识,如何去合理正确的看待事物,如何形成适合自己发展的思维体系。本专栏既是对过去思考的总结,也是对自己发展所具备的能力的思考,希望这些内容能陪我成长,帮大家解疑答惑。该专栏首发今日头条,关注我的同名头条号和微信公众号获取更及时的内容推荐。
版权声明: 本文为 InfoQ 作者【菜根老谭】的原创文章。
原文链接:【http://xie.infoq.cn/article/d997719bc3905ac386ed24e45】。文章转载请联系作者。
评论