软件架构设计的真正目的是解决软件复杂度带来的问题,软件复杂度由来主要由三方面:高并发场景下的对软件高性能要求、业务场景对软件高可用要求、持续变化的业务以及业务扩张和增加需求对软件扩展性的要求,除此外,对低成本、安全、软件规模也一定程度上增加了软件设计的复杂度。
在解决每个复杂度维度上,分别有各自的应对解决方案:
在低成本、安全、规模方面,技术革命创新、功能和架构安全、软件规模量变引发质变(微服务就是典型例子),这些因素也增加了软件的复杂度。
然而我们往往忽略了在软件开发阶段,因为需求的理解不到位等导致的开发返工以及因为原班开发人员离职带来的交接文档的缺失,导致新人接手项目的高上手成本、高沟通成本和高维护成本。是否存在有效的方法能够在开发人员开始编码之前能解决这一问题呢?
领域驱动设计(Domain Driven Desing,简称DDD)就是在可扩展性方面将复杂多变的业务排除在稳定不变的内核业务之外,从而在多变的环境中找到不变的部分,达到以不变应万变的目标。不仅如此,DDD还能够以更优于静态文档的方式提供开发人员,业务人员所需要的业务知识,因为DDD在设计之初就要求业务人员特别是领域专家与开发人员通过双方统一的语言一起来协作设计系统,最终交付给业务人员能够“读”得懂的,符合其期望的产品,尽管这一愿望很激动人心,但实施过程并不顺利,但无论如何我们也应该坚持这一目标,就像DDD作者总结的那样,会给整个团队甚至公司带来的益处远超过因为学习DDD带来的成本,这些优势归结起来如是:
• 使领域专家和开发者在一起密切合作,这样开发出来的软件能够准确地传达业务规则。“准确传达业务规则”的意思是说,此时的软件就像是领域专家所开发出来的一样。
• 可以帮助业务人员自我提高。没有任何一个领域专家或者管理者敢说他对业务已经了如指掌了,业务知识也需要一个长期的学习过程。在DDD中,每个人都在学习,同时每个人又是知识的贡献者。
• 关键在于对知识的集中,因为这样可以确保软件知识并不只是掌握在少数人手中。
• 在领域专家、开发者和软件本身之间不存在“翻译”,意思是当大家都使用相同的语言进行交流时,每人都能听懂他人所说。
• 设计就是代码,代码就是设计。设计是关于软件如何工作的,最好的编码设计来自于多次试验,这得益于敏捷的发现过程。
• DDD同时提供了战略设计和战术设计两种方式。战略设计帮助我们理解哪些投入是最重要的;哪些既有软件资产是可以重新拿来使用的;哪些人应该被加到团队中?战术设计则帮助我们创建DDD模型中各个部件。
就像其他高回报率的投入一样,DDD需要我们在时间和精力上都有所投入。但是,考虑到我们在开发软件的过程中经常遇到的各种问题和挑战,这样的投入是值得的。
分层架构模式被认为是所有架构的始祖。在自然界中,大到宇宙天体,小到原子的运行模式。在人类社会中,大到国际组织,小到团体的组织模式,都采用层次结构。在软件架构中,从早期的网络七层协议,操作系统的内核架构到广泛使用的MVC软件开发架构,都在使用分层架构,可见分层模式经久不衰。 分层架构的好处是显而易见的,首先,由于层间松散的耦合关系,使得我们可以专注于本层的设计,而不必关心其他层的设计,也不必担心自己的设计会影响其它层,对提高软件质量大有裨益。其次,分层架构使得程序结构清晰,升级和维护都变得十分容易,更改某层的具体实现代码,只要本层的接口保持稳定,其他层可以不必修改。即使本层的接口发生变化,也只影响相邻的上层,修改工作量小且错误可以控制,不会带来意外的风险。 分层架构的一个重要原则是每层只能与位于其下方的层发生耦合。分层架构可以简单分为两种,即严格分层架构和松散分层架构。在严格分层架构中,某层只能与位于其直接下方的层发生耦合,而在松散分层架构中,则允许某层与它的任意下方层发生耦合。
下图A中所示为一个典型的DDD系统所采用的传统分层架构,其中核心域只位于架构中的其中一层,其上为用户界面层(User Interface)和应用层(Application Layer),其下是基础设施层(Infrastructure Layer)。