最近在做项目重构和功能改进。我做了很多设计,也发生过一些纠纷。其实综上所述,很多争议早已成为经典问题。这些问题没有优劣之分,采取何种解决方案取决于当地情况,并在做出决定之前详细分析项目需求和复杂性。过去,很多人试图仅从宏观指导思想来决定设计。最后大家都不服别人,还是先确定问题吧,至少以后想问题会比较直白。1.分裂与融合从现实世界的角度来看,事物是相互联系的。从这个角度来看,任何事物的分裂都不完全正确。然而在软件开发中,人的理解能力是有限的,拆分似乎是降低单个项目复杂度最有效的方法。分裂有很多层次。最小的可能就是拆分代码段,将单个函数替换为多个函数,再将单个类替换为多个类。在Java中也可以拆分包,再拆分jar包,最后拆分成不同的项目。一个项目该不该拆,怎么拆,之前也有很多争论。对此,我的建议是:拆不拆没有对错之分,Windows是微内核架构,Linux是单内核架构。微内核就是内核很小,可以补充很多模块,内核和模块是解耦的。Linux是单内核,这意味着所有内核函数都将在编译时确定。大家可能觉得微内核更好,很多时候确实更好,但是Linus有一个经典的论断:“你不需要管理单个模块,但是你需要处理模块之间的依赖关系,这可能会更比模块本身复杂”。因为事物本身是相互联系的,你感觉它们之间没有耦合,但是在现在的使用场景下用不到。系统内部对外透明,保留选择拆除与否的权利。项目本身的复杂性可以通过内部实现来解决,外部维护约定的API,这样以后内部重构就会简单很多。反之,如果暴露了内部实现,那么修改就困难了。对于项目拆分,如果没有充分的理由支持拆分,就不要拆分。不成熟的拆分最常见的结果是,随着需求的变化,你不得不打破这种解耦关系,这会导致更多的问题。建议等需求稳定后再考虑拆分。在系统内执行更多代码级拆分以管理复杂性。与项目的拆分相比,在函数和类层面拆分成本很低,值得多用。2.配置和灵活性如果一段代码只用一次,那么我们可以直接通过代码来实现。如果我们有几十个或上百个类似的任务,那么我们不想写重复的代码,我们希望能够配置几个不同的参数来实现不同的任务。如果以后还有变化的需求,我们连配置都不想自己写,而是有一个运维后台让需求方(可能是不懂开发的人)直接完成配置。基于配置的开发方法往往很容易让开发人员忽略成本。这种配置最近有一个很流行的名字,叫做DSL。但实际上,配置和灵活性是矛盾的,配置的表达能力自然弱于通用语言。当然,也有人试图用配置来解决所有问题,结果发明了一种很难用的语言。我自己的框架WebMagic是配置与灵活性权衡的典型示例。WebMagic是一个垂直爬虫框架。爬虫最复杂的是规则的编写。您可以将其视为可配置的东西。公司以此为基础做了配置后台。尽管如此,还是有一些情况需要手写Java代码来实现一些功能。对于这个问题,我的建议是:先写代码解决问题,但要提前约定好接口。第一阶段,没有人能预知未来的需求,所以先用自己熟悉的代码实现。根据您的输入和输出,您可以约定程序级接口。与配置相比,这通常更容易。如果接口设计得当,也会有很大的灵活性,以后基本不用改动。有了一定的积累之后,再根据之前的任务进行配置。配置内容是什么?首先,公共逻辑必须在整体框架中,配置内容应该是不同任务特有的部分。配置格式,或者DSL的语法约定,应该首先基于现有的任务,然后可能考虑未来的情况。我是一个实用主义者,所以我会更多地参考现有情况。如果我发现这个配置框架不能满足前面的任务,那么我就需要思考它的可行性和必要性。始终保留使用代码实现的能力。我是一个实用主义者。有了配置,如果你不提供实现代码的能力,有一些复杂的需求,那么只能扩展配置的能力。这可能只会导致配置解决方案框架变得极其庞大和复杂,而相对收益却很低。这时候通过配置解决大部分问题,再通过代码解决少数问题也是一个不错的选择。3.总结其实还有很多东西没有说到,后面再补充。以上建议都是建议,不一定是最合适的方案。欢迎讨论。一句话总结:软件设计应该适应和满足需求,同时不断发展。本文来自:http://my.oschina.net/flashsword/blog/280096
