避免过度设计

许多文章都在强调不要过度设计自己的系统,但是没有道出个所以然来,所以本文列出一些经典的过度设计,希望能给你带来启发,在工程上做一些平衡,避免过度设计把我们推到另外一个复杂度上

1、Engineering is more clever than Business

工程师通常认为自己是最聪明的,这第一个错误容易让自己过于工程化。我们计划了100件事,业务方会提出我们之前没有考虑到的第101件。如果我们解决了100个问题,那么接下来还可能会有1000个问题。我们以为一切都是掌握之中,然而实际完全不知道未来会发生什么

在研发生涯中,从未碰到过业务在需求上是收敛,它们总是发散的,这是业务的本来面目,不是产品经理的错

2、Reusable Business Functionality

当业务方提出了越来越多的需求时,我们第一反应是尽量分组和泛化业务,这是大部分MVC架构最后成为由大量模型或者控制器堆积的原因,正如前面所说的,业务永远不会是收敛的,它们总是发散的

在系统中,共享逻辑和抽象应该是趋于稳定的,然而随着功能迭代越来越多,它们要么会保持平稳,要么会变得脆弱。当相反的情况发生时,就会成为太大而失败的系统

比如说,有个业务是实现用户属性管理,我们持着任何东西都是相似的这种观点,首先完成通用的CRUD逻辑,但是这个需求实际上要求满足13个不同的注册流程,也就是说通用的逻辑代码没有任何意义。同理,一个订单视图和订单编辑视图流程是完全不一样的,可偏偏有些人会合并视图

我们在横向分割业务前,应该先尝试纵向分割,同时也要考虑从一种方式切换到另外一种方式的可操作性和便捷性,否则重写系统将是灾难性的工作,也就是说分离行为比强行合并好

3、Everything is Generic

需要连接数据库,那就写个通用的泛化适配器
需要查询数据库,那就写个泛化查询
需要对参数进行校验,那就写个通用的参数校验器
需要对结果进行包装,那就写个通用的数据映射器
等等

当在实现需求时,浪费大量的时间尝试总结出完美的抽象层,甚至原本业务问题的答案非常显而易见。即使奇迹般地总结出了一个完美的抽象时,它往往会很快变得不适用,目前最好的代码设计侧重点应该是编码易于被删除的,而不是盲目追求易于扩展

实际上,重复代码比错误的抽象更好,只有当你看到系统里有逻辑重复的代码,才能更好地进行抽象,同时重复代码暴露了许多用例,有助于使得边界上下文清晰

4、Shallow Wrappers

我们习惯使用外部库时都封装一层,这种封装是浅层的,不幸的是,我们容易在提供功能和编写好的包装器之间模棱两可,混淆着大量的业务逻辑,使得它既不是一个好的包装器,也不是一个好的业务解决方案。实际上要封装一个优质的库,需要投入大量的时间编写,同时保证高代码质量和完善的代码测试,具备清晰、可测试的、可测量的API。需要注意的是,封装应该是例外,不应该是常态,不要为了封装而封装

5、Applying Quality like a Tool

高质量的代码通常满足SOLID原则,使用相应的设计模式和代码技术,比如factory、builder、strategy、generics、enums。如果你不加思索地运用质量概念,比如说将所有的变量修饰修改为private final,这并不能将编码质量提高,或者改变过去链式继承的方式,每个类都有接口和实现,然后注入到下一层,看似满足SOLID概念。实际上SOLID的设计初衷是为了反对滥用继承与其他OOP概念,然而大部分工程师没有搞清楚这些概念从哪里来,如何出现,只是照单全收,没有从思维上消化,只是工具化地盲目应用

学习一门其他语言,尝试以另外的思维模式去做事情,这样会成为一个更好的开发者。新瓶装旧酒对我们没有任何帮助,我们不必为了应用一个新概念而弄乱一个清晰的设计

6、Overzealous Adopter Syndrome

发现了泛型技术,将一个简单的 "HelloWorldPrinter" 修改成了“HelloWorldPrinter”,那怕事实上只会有特定的数据类型,或者有足够的普通类型签名

发现了策略模式,现在每个条件语句都是一个策略

到处使用枚举/扩展方法/Traits等各种炫酷的技术

上面都体现出了过度适配问题

7、<X>–ity

例子1、实现一个CMS系统,要求具备可扩展性,业务人员可轻松添加字段
结果:业务人员从来不使用这个功能,当他们需要时,会要求工程师在旁边协助,也许我们所需要的只是一个简单的开发人员指南,可以在几个小时内添加一个新字段,而不是点击式界面

例子2:设计一个可轻松配置的包罗万象的数据库层,我们可以通过文件配置轻松切换数据源
结果: 过了很长时间因为某种原因需要切换数据源,但是修改配置文件无法满足我们的要求,现在业务有了很多的功能差距,导致不兼容

实际上,建议将数据库视为解决方案的一部分,抛弃可配置性,否则很难保证兼容性。当设计时,多问自己使用场景是什么,然后深挖下去,你可能会发现大部分特性都是没有必要的,包括可配置性、安全性、可扩展性、可维护性、可继承性。总之,不要在没有被要求时加上各种特性,应该明确地定义与评估场景、用户故事、需求、用途

文章翻译修改自:

https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8

文章来源:www.liangsonghua.me

作者介绍:京东资深工程师-梁松华,在稳定性保障、敏捷开发、JAVA高级、微服务架构方面有深入的理解

原文地址:https://www.cnblogs.com/liangsonghua/p/11306460.html

时间: 2024-08-30 06:33:15

避免过度设计的相关文章

架构的坑系列:重构过程中的过度设计

架构的坑系列:重构过程中的过度设计 软件架构   2016-06-03 08:47:02 发布 您的评价:       5.0   收藏     2收藏 这个系列是 坑 系列,会说一些在系统设计,系统架构上的 坑 ,这些都是我想到哪说到哪,有像这篇一样比较宏观的 坑 ,后面的文章也会有到具体技术细节的(比如某个函数,某个系统调用) 坑 ,总之,到处都是坑,这些坑有些是我经历过的,有些是听说的,你也可以留言说说你遇到的 坑 . 这一篇,我们从 重构 这个场景来看看系统架构的设计中 过度设计 这个坑

坑系列 --- 重构过程中的过度设计

这个系列是坑系列,会说一些在系统设计,系统架构上的坑,这些都是我想到哪说到哪,有像这篇一样比较宏观的坑,后面的文章也会有到具体技术细节的(比如某个函数,某个系统调用)坑,总之,到处都是坑,这些坑有些是我经历过的,有些是听说的,你也可以留言说说你遇到的坑. 这一篇,我们从重构这个场景来看看系统架构的设计中过度设计这个坑. 首先,我们这里说的重构,和<重构:改善既有代码的设计>这本书中的重构不太一样,这是本好书,他主要说的是代码级别的重构,这种重构是需要在编码的时候时时刻刻进行的,更多的是一种编程

企业开发珠玑-过度设计

一.过度设计一般起源于对需求太多的计划,预测和猜想.要知道"计划赶不上变化"是普遍真理.所以因时,因地制宜才是最重要的.用国外传过来的词就是"敏捷开发". ------顺便吐槽一下"敏捷开发","迭代开发","瀑布流"这些争论.挺扯淡,其实都是要看人员,资金,时间等各方面的条件,那些贬此扬彼都是为理论而理论,或者别有用心. 二.怎么规避过度设计?不管时敏捷还是瀑布,都要避免过度设计.说些个人经验,架构设计的

2014年的项目的总结(二) 谨防过度设计 别为显示技术而搞复杂 杀鸡焉用牛刀?

14年最后一个项目无疑收获巨大,自己掌握的很多东西都得到了检验,而其中暴露出来的问题更让我得到教训,特别是开始走入的过度设计的误区,为了显示技术什么复杂用什么,现在想想真是后背发凉.这样的经历,像我这样的新手估计很容易犯吧. 上图 开始的架构 一开始做设计时,为了统一所谓的对外接口,解决耦合问题,防止action层与service层多对多的复杂关系,使用façade(外观模式)将对应模块的多个service做了下轻封装,想象中的层次关系是左边这样的,将左边换成右边,怎么看都是右边更顺眼,所以加了

基本上,把switch,用设计模式代替,肯定是bug和过度设计。想想,本来修改一个文件几行代码可以解决的问题,变成修改3-6个类才能实现一样的功能。不是傻是什么?

那些迷信设计模式的人,来修改一下这个方法吧.看看你最终的代码膨胀为几倍... public virtual PasswordChangeResult ChangePassword(ChangePasswordRequest request) { if (request == null) throw new ArgumentNullException("request"); var result = new PasswordChangeResult(); if (String.IsNul

不要进行过度设计,某一层存在真的有意义吗?是否可以更简单。

曾经要对一个客户的老项目进行维护开发 这个项目单单数据的访问有把接口一起算进来有11层. 当时要修改这个项目的时候真的是要发疯. Supplier.EIA_GetVenueAgentAccounts()IEIAVenueAgent EIAVenueAgent  .ListAgentAccounts()  IEIAVenueRepositoryEIAVenueRespository .ListAgentAccounts()   把datatable转成 实体IEIADataFactoryEIADa

Android App的设计架构:MVC,MVP,MVVM与架构经验谈

来源: Android App的设计架构:MVC,MVP,MVVM与架构经验谈 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于App的架构如何设计: 我的App需要应用这些设计架构吗? MVC,MVP等架构讲的是什么?区别是什么? 本文就来带你分析一下这几个架构的特性,优缺点,以及App架构设计中应该注意的问题. 1.架构设计的目的 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.这样做的好处是使得程序在开发的过程中,开发人员

好的用户界面-界面设计的一些技巧

原文地址:http://www.cnblogs.com/Wayou/p/goodui.html 如此有用的文章我已记不得是什么时候发现的了,但在看完的那一刻便想将之翻译,分享给大家自己也受用. 时间过了很久,来到了2014年,终于静下心来花了大把时间连同图片一起译成了中文.像我这样业余的翻译六级分数只够及格的程序员,不敢说做到信雅达,但求意思到位. 1 尽量使用单列而不是多列布局 单列布局能够让对全局有更好的掌控.同时用户也可以一目了然内容.而多列而已则会有分散用户注意力的风险使你的主旨无法很好

从涂鸦到发布——理解API的设计过程(转)

英文原文:From Doodles to Delivery: An API Design Process 要想设计出可以正常运行的Web API,对基于web的应用的基本理解是一个良好的基础.但如果你的目标是创建出优秀的API,那么仅凭这一点还远远不够.设计优秀的API是一个艰难的过程,如果它恰巧是你当前的工作任务,那么你很可能会感到手足无措. 不过,优秀的设计绝对是可以实现的.本文所描述的流程将帮助你获得成功,我们将共同研究什么是优秀的设计,以及迭代式的流程如何帮助我们实现这一目标.我们还将叙