【软件设计】什么是分离关注点?

软件设计之分离关注点

大多数系统的设计做得不够好,问题常常出现在分解这步就没做好。常见的分解问题就是分解的粒度太大,把各种维度混淆在一起。我们在分解问题的时候,会有很多维度,每一个维度都代表着一个关注点,这就是分离关注点。分离关注点,发现的关注点越多越好,粒度越小越好。可以分离的关注点有非常多,只要稍微注意一下,就能识别出来。但还有一些你可能注意不到,结果导致了混淆:

- 常见错误:把业务处理和技术实现两个关注点混在了一起

例:如果现在业务的处理性能跟不上,你有什么办法解决吗?
大多数程序员的第一反应是,多线程。多线程的确是一种解决办法。但如果不加限制地让人去把这段代码改成多线程的,一些多线程相关的问题也会随之而来。比如,资源竞争问题、数据同步问题等等。写好业务规则和正确地处理多线程,这是两个不同的关注点。如果我们把二者放到同一段代码里去写,彼此影响也就在所难免了。只有问题说明白了,解决方案才能清楚,那就是把业务处理和多线程处理的代码分开。按照我的理解,大部分程序员都不应该编写多线程程序,而是应该由专门的程序员把并发处理的部分封装成框架,让大家在里面写业务代码就好了。把业务处理和技术实现混在一起,类似问题还有很多。比如我们经常问到的怎么处理分布式事务,怎么做分库分表等。其实我们更应该问的是,我的业务需要分布式事务吗?我是不是业务划分没有做清楚,才造成了数据库的压力?在真实项目中,程序员最常犯的错误就是认为所有问题都是技术问题,总是试图用技术解决所有问题。任何试图用技术去解决其他关注点的问题,只能是陷入焦油坑之中,越挣扎,陷得越深。

- 常见的错误:不同的数据变动方向

例:有人问过我这样一个问题:在 Java 应用里,做数据库访问用 Spring Data JPA 好,还是MyBatis 好。Spring Data JPA 简化了数据库访问,自动生成对应的 SQL 语句,而MyBatis 则要自己手写 SQL。普通的增删改查用 Spring Data JPA 非常省事,但对于一些复杂场景,他会担心自动生成SQL 的性能有问题,还是手写 SQL 优化来得直接。随即我又问了他一个问题,为什么需要复杂查询呢?他告诉我,有一些统计报表需要。不知道你是否发现了其中混淆关注点的地方?普通的增删改查需要经常改动数据库,而复杂查询的使用频率其实是很低的。从本质上说,之所以出现工具选择的困难,是因为他把两种数据使用频率不同的场景混在一起所造成的。如果将前台访问(处理增删改查)和后台访问(统计报表)分开,纠结也就不复存在了。不同的数据变动方向还有很多,比如:

  • 动静分离,就是把变和不变的内容分开;
  • 读写分离,就是把读和写分开;
  • 前面提到的高频和低频,也可以分解开;
    ……
    不同的数据变动方向,就是一个潜在的、可以分离的关注点。
    在实际的项目中,可以分离的关注点远不止这些。做设计时,你需要一直有一根弦去发现不同的关注点。分离关注点,不只适用于宏观的层面。在微观的代码层面,你用同样的思维方式也可以帮助你识别出一些混在一起的代码。比如,很多程序员很喜欢写 setter,但真的有那么多要改变的东西吗?实际上可能就是封装没做好而已。分离关注点之所以重要,有两方面原因。一方面,不同的关注点混在一起会带来一系列的问题,正如前面提到的各种问题;另一方面,当分解得足够细小,就会发现不同模块的共性,才有机会把同样的信息聚合在一起。这会为软件设计的后续过程,也就是组合,做好准备。

你可能感兴趣的:(软件设计之道,架构)