
上QQ阅读APP看书,第一时间看更新
业务与基础设施分离
不过,如果有一个消费者(一个业务系统),它根本不使用HTTP协议怎么办?比如使用消息队列,或者自定义的Socket协议来进行通信,应用程序如何处理这种场景?这种情况就好比你看到了这样一个函数:

作为程序员,自然会做一次抽象,将协议作为参数传入:

更进一步,protocol可以在service之外构造,并注入到应用中,这样代码就可以适配很多种协议(比如消息队列,或者其他自定义的Socket协议)。比如:

类似的,对于数据的持久化,也可以使用同样的原则。对于代码中诸如这样的代码:

在修改之后会变成:persistenceTo(data, repository);
应用依赖倒置原则,我们会写出这样的形式:

对于Repository可能会有多种实现。根据不同的需求,我们可以自由的在各种实现中切换:

这样业务逻辑和外围的传输协议、持久化机制、安全、审计等等都隔离开来了,应用程序不再依赖具体的传输细节,持久化细节,这些具体的实现细节反过来会依赖于应用程序。
通过将传统内置在层次架构中的数据库访问层、通信机制等部分的剥离,应用程序可以简单的分为内部和外部两大部分。内部是业务的核心,也就是DDD(Domain Driven Design)中强调的领域模型(其中包含领域服务,对业务概念的建立的模型等);外部则是类似RESTful API,SOAP,AMQP,或者数据库,内存,文件系统,以及自动化测试。
这种架构风格被称为六边形架构,也叫端口适配器架构。