按六角形架构实现模块化设计



六角形架构是核心与接口外围关系图,业务逻辑核心应该位于中心,不依赖于外层接口,注意,这里数据库也是一种外围,很多系统能做到业务逻辑不依赖rest或界面,但是做不到不依赖于数据库。违背六角形架构的应用属于坏的单体应用,几乎无法迁移到微服务,只有进行重构模块化后才能迁移,而模块化是否成功的标志是能否使用maven实现你的业务模块打包。本文提供了几种模块化建包的方法。

首先按照功能打包,包的名称不应该像这样:“dto”, “common”, “mvc”,包的取名划分也有利于Maven使用,反过来如果一个系统业务模块不能用Maven配置的话也说明其耦合很紧,你需要按照功能划分包,用功能名称取名称包名,所谓功能指的是业务逻辑。例如,如果你的系统是关于网上购物,你的包应该看起来像“产品”,“购物车”等等。记住,Java是一种面向对象的语言。替换任何过程性代码,并将其打包到带有正确名称的对象中。不要害怕复杂类的初始化,这就是工厂模式的目的。代码性能现在不是问题所在。

其次,将存储库和客户端代码与核心业务逻辑中剥离分开,分离出所有数据库访问类(SQL查询!)、方法和所有客户端(如API、队列、侦听器等),使用接口将核心类与上面这些具体类进行隔离。它们不应该与你的核心可靠的逻辑混在一起。记住,数据库/API/Queue只是细节,是手段方法,但不是目的。

这样你的包导入不应该导入具体实现类:

import com.company.core.magicworker.SomeWorkerImpl.class

而应该导入接口:
import com.company.core.worker.SomeWorkerInterface.class

接口音应该放在更抽象的更高一层次的包里,更高更抽象的包不应该依赖更低层的实现。

应该使用接口来跨越包边界。假如你的系统中有报表功能或Web接口,你可能使用不同的包实现,那么最好使用接口与他们进行交互。

DDD(DomainDrivenDesign)中实体可能代表数据库表,但却是系统的业务对象,如:产品、支付、用户等。它们应该放在代码库的核心中,如果可能的话不应该与具体数据表有任何依赖关系。

按照上面的方法独立出你的包,或者可以将它们放置在Maven、Java 9模块、单独的Jar/WAR文件等形式中。如果能放置成功,下一步就可以尝试将它们迁移为单独的微服务,注意要消灭避免循环依赖,循环依赖这事在使用Maven打包时就可能会出现,并必须解决。

原文



[该贴被banq于2018-08-12 17:42修改过]