开云体育 开云官网什么是软件开发中的过度设计?
-----------请大家相信我,这个真的是来自天才小熊猫的新浪微博。
补充下:楼上高分答案谈的是“功能上的过度设计”,可以理解为发生在产品经理身上的问题。
顶楼童鞋举的例子很精彩,不过过于极端了,实际上的过度设计往往发生得隐蔽和普遍得多。
简单来说,过度设计就是进行了过多的面向未来的设计,进行了不必要的抽象封装,为系统增加了不必要的复杂度。
举个例子,你要做一个功能模块,但你考虑到到这个系统里还有几个未完成的模块和你要做的东西类似,所以你决定为此额外做一些抽象和封装,以便将来复用。然而到后来你开发那些相似的模块时你才发现,可能是由于抽象不足或抽象错误,你不得不重新修改之前的封装才能完成复用,导致最终成本实际上还不如不做;或者你发现复用的部分所降低的成本实际上还不如包装花费的成本。 这些都是最常见的过度设计的例子。
程序员在掌握了一些基本的设计能力之后,最常见也是最难克服的设计问题往往就是过度设计。上面的错误我相信大多数人都一而再,再而三的的过。
虽然是两个相对的概念,但设计不足和过度设计绝大多数时候都是一起出现的。都是最常见的设计问题。设计不足不仅常见于新手,老手也常。甚至我还见过有一类老程序员在经历过多次过度设计的打击之后,转向另一个极端,否定抽象封装的作用,走上“反设计”的道路。
过度设计和设计不足的平衡问题没有很好的解决办法,只有依靠经验的积累和不断的总结思考。如何把握这个度是最能考验程序员的经验和价值的问题之一。
我所尝试过的软件方法中,有一种方法的思维方式对于解决这个问题帮助最大,就是TDD(测试驱动开发),这里简单说下为什么TDD能解决这个问题:
TDD的一个核心思想是小步增量,不断重构。具体说来就是TDD有两个状态(常见的说法是两顶帽子):
状态A:用test case描绘需求,并使用最简单的方式满足这个test case。注意要用最简单的方式满足这个需求,不能为任何test case之外的需求做任何设计。 test case通过之后进入状态B;
状态B:重构代码,让现有的代码在尽量保持简单性的同时足够优雅清晰。注意此时你只能对现有的实现代码进行重构,不能增加任何新的功能和test case。
整个TDD的过程就是在这两个状态间不断转换的过程。在状态A增加功能,在状态B优化设计。
TDD的这种思维方式走的稍微极端一点。它直接排斥任何对未来的设计,转而以优雅简洁的设计和test case来为未来需求的重构降低成本。 可以说严格遵循TDD做出来的设计必然在过度设计和设计不足方面都不会有太大的问题。
我严重推荐TDD。不管你最终会不会接受TDD这种开发方式,它独特的思维方式都必然会给你的设计观念带来很大影响。
十多年前,那时“美女”这个称谓还是非常稀缺值钱的,被这么称呼的女性同胞占比,也就是不到10%的样子。
后来就愈发不可收拾了,只要是个女的活的,下至5岁上至50岁的,99%都被人称呼过“美女”。
当然,现在互联网行业的架构师,也越来越“美女化”了,基本上有个两三年工作经验的,带两三个应届生负责过一两个QPS不过十,用户量不过千的小系统的,把项目用SSM框架给搭建起来的,也都成架构师了。
而这些所谓的“架构师”们,如果仅仅是title上的改动,平时工作中该撸代码就撸代码,该摸鱼看网页就看网页,其实也真的没什么。
最最最最怕的就是,他们觉得自己的身份已经变了,是时候该体现出自己作为系统架构师价值的时候了,那一切就会变得不可收拾了。
这些架构师们体现价值的方式当然是做架构设计。按照他们的话说,系统架构要具备前瞻性、灵活性、复用性、伸缩性、可维护性、可扩展性、低耦合性、高内聚性、可移植性。当然,基本上90%都是过度设计。
不久前我面试过一个中小厂架构师,看他的简历上赫然写着,“主导XX系统从单体服务往微服务架构演进工作”。
然后我问他的问题是:”详细说下微服务拆分这件事情,包括:微服务拆分的原因、时机和拆分后的粒度。“
那个这个架构师说的第一句话就把我雷到了:”微服务拆分的粒度,我认为越细越好,不然为什么叫微服务呢?而且,现在的一个很小的微服务,随着业务的持续迭代演进,未来都有可能变得非常庞大,我们做架构设计的,必须要具备前瞻性。“
他接着说:”我们的微服务不但按照业务模型进行的拆分,而且我还按照controller层、service层和dao层也做了拆分,这样可以提升代码复用性,你想用我哪层的代码,就可以调用我哪层的API。“
我心里感慨到,今年阿里云和腾讯云业绩能不能达标,全看这类架构师的了,他们是线张表
三年后,各个大小互联网公司纷纷跟进,争相建设自己家的中台,也就在这时,某独角兽公司的架构师老范过来找我取经。
福厂收购了某公司,在收购后的一次技术交流中,我听到对方公司的首席架构师说:“MQ是个好东西,能异步处理,能消峰,能解耦,还是应该在项目中多用用的。”
后来发现,大首席架构师的下级执行力真强,MQ真的在他们的项目中无处不在:
打业务日志的场景用MQ,且其生产者和消费者是同一个服务,就是为了用MQ异步打一行日志;
对,对,还是上次的那个首席架构师,他除了爱用消息队列外,还特别喜欢用缓存,而且是Guava Cache + Redis的多级缓存。
据同事说,这种多级缓存策略在这位首席架构师的熏陶下,已经遍布了OA系统、公司官网、消息中心、结算系统、供应链系统、CRM系统。
记得我刚上班不久,组内有一个架构师同事,写的代码巨复杂,各种技巧、设计模式、高级语法满天飞,还沾沾自喜的给我们炫耀。
一次Code Review的时候,我嘴欠问他这里咋这么设计,他就鄙视的说:“你连这个都不知道,这是设计模式中的建造者模式啊。”
前面说的那些架构师们,他们过度设计所带来的后果是浪费服务器和研发资源,但架构师老邓不一样,他的过度设计是浪费表。
为什么不能写存储过程?一个重要的原因就是业务逻辑放到数据库里会导致数据库移植成本变大。
我厂某团队的架构师老李素以严谨著称,其经常放在嘴边的一句话就是:“工程师不仅仅是一项有创造性的职业,也是一门严谨审慎的职业。”
还是上面的那个架构师老李,他要求团队代码中带数字的地方,全部走配置中心,这样可以不发布代码就直接进行修改。
遇到这种类型的架构师,真的特别想把他们祭天了,因为我是Kiss原则的忠实拥趸。
的答案虽然很搞笑,但是其实不准确,它混淆了程序设计和产品设计的概念。图中的软件虽然最后变得十分诡异,但其实每一个新版本都忠实地实现了新的需求。变得诡异的是需求,而不是程序设计。
程序设计的一切都应该以需求为准。程序的过度设计,并不是你实现了太多的功能,而是为了实现太多你觉得会出现结果没有出现的需求,导致系统架构过于庞大复杂。所以通常一个程序是否被过度设计,看界面是看不出来的。。。
过度设计这个东西就是想太多,希望你的程序能应对一切需求的变化,希望你的程序拥有一切牛掰的特性,但实际上你水平就在这里所以你做不到。一旦你想做的超出了你的水平,你很可能把自己绊住,根本实现不出来;或者实现出来太过复杂导致bug多多效率低下;或设计歪了,你发现意料之外的需求根本都加不进去了!
没办法,设计是否合适,这很大程度上就一个靠主观判断的事,没有经验就没法分辨,必须多写多看多思考。失败是成功的麻麻,只要想做出合适的设计,不当的设计就是必经之路。你想的经常不会发生,发生的总能刷新你的世界观。不每天来刷刷经验,怎么能更好地认识世界呢_(:3」∠)_大牛们其实就是刷出来的,哪些需要哪些不需要,哪些做完了维护成本可能会比修改成本还要高,怎么做效率更高,怎么做可以降低耦合度。。。当然,就算世界观圆润的大牛们也会失足的(ノ)´௰`(ヾ)Kaiyun 开云Kaiyun 开云
扫一扫关注微信公众帐号