前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ARTS-21-避免过度设计

ARTS-21-避免过度设计

作者头像
公众号_松华说
发布2019-08-06 15:27:56
3990
发布2019-08-06 15:27:56
举报
文章被收录于专栏:松华说松华说

ARTS的初衷

Algorithm: 主要是为了编程训练和学习。

Review:主要是为了学习英文

Tip:主要是为了总结和归纳在日常工作中所遇到的知识点。学习至少一个技术技巧。在工作中遇到的问题,踩过的坑,学习的点滴知识。

Share:主要是为了建立影响力,能够输出价值观。分享一篇有观点和思考的技术文章

https://www.zhihu.com/question/301150832

一、Algorithm

二、Review

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

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

三、Tip

并行程序设计模式,包括Future模式、Master-Slave模式、保护暂停模式、不变模式、生产消费者模式等 (1)、Future模式,服务程序不等数据处理完成便立即返回 (2)、Master-Slave模式,Master线程负责接收和分发任务,Worker线程负责处理子任务,每个Worker线程只处理部分任务 (3)、保护暂停模式,仅当服务进程准备好才提供服务 (4)、不变模式,通过回避问题而不是解决问题的态度来处理多线程并发访问控制,如不可变字符串 (5)、生产消费者模式,生产者线程向内存缓冲区提交任务,消费者线程从内存缓冲区获取任务并处理

四、Share

leetcode并发题目解题报告JAVA版-透过问题看并发编程注意事项和技巧

leetcode并发题目解题报告JAVA版

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 松华说 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Algorithm
  • 二、Review
  • 三、Tip
  • 四、Share
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档