清洁建筑中的依赖规则声明:
..。该源代码依赖项只能指向内部。
我现在遇到了一个我自己也搞不懂的问题。
假设我有一个具有应用程序业务规则abr
的模块和两个用于实现来自abr
接口的服务的模块。
+---------+
| abr | Business Layer (defines interfaces
+---------+ 'Service1' and 'Service2')
+----^ ^---+
- - -|- - - - - - - - - |- - - - -
| |
+-----+----+ +-----+----+
| service1 | | service2 | Dependencies (implement Interfaces
+----------+ +----------+ define in abr)
现在,这两个服务使用网络库OkHttp
,并且应该对它们的请求使用相同的用户代理字符串。
不幸的是,我不知道如何很好地实现这一点。
可能的可能性有:
sharedokhttpconfig
的模块on,这违反了on规则abr
不应该知道的网络,甚至服务使用okhttp。另一个例子是,这个项目有两个不同的UI模块,它们本质上是不同的,但是它们中的一些逻辑是相同的。
例如格式化用户的地址。
对如何处理这件事有什么建议吗?
为了澄清为什么我认为这会违反依赖性规则。
abr
是我的应用程序的中间部分,它不应该知道UI或其他任何东西,所以所有依赖项都必须指向它的方向。
但是当我添加两个模块所依赖的模块时,在我看来,它们似乎是指向外的。
+---------+
| abr |
+---------+
+----^ Inwards ^---+
| |
+-----+----+ +-----+----+
| service1 | | service2 |
+----------+ +----------+
| Outwards? |
+----v v---+
+---------+
| snbl | snbl = share non-business logic
+---------+
或者这样做还行,因为从abr
的角度来看,没有什么改变吗?
发布于 2017-08-22 04:11:50
经过与“任择议定书”的讨论,我们得出了以下共同的结论:
这两个服务的接口被声明为业务逻辑的一部分,而它的实现不是它的一部分。因此,如果这些实现依赖于OkHttp
的配置数据,这是有意义的。
向前迈进的最有希望的解决方案是声明模块snbl
(其中包括配置数据),并将服务与实现圈在一起。那么,这些数据与OkHttp
的配置数据之间的依赖关系并不违反依赖关系规则。
发布于 2017-08-23 10:32:55
我只想在接受答案中添加一些内容,以及对布朗博士的有洞察力的回答进行扩展。Bob叔叔的清洁建筑中隐含的是,“在”所有东西下面都有每个循环所依赖的一些公共基础结构(例如,随语言提供的标准库,以及其他可以选择作为标准的组件)。
因此,这可以归结为决定OkHttp
库所需的隔离级别。让我们先假设您的“依赖”层或多或少对应于Bob叔叔的“接口适配器”循环;如果您不介意这个层/圈直接依赖于OkHttp
,那么您可以将snbl
放在那里,并让它直接引用OkHttp
。
另一方面,如果您希望避免依赖于OkHttp
,那么您可以应用与业务层完全相同的依赖反转技巧。这实际上是右下角插入的内容;但下面是I 找到在互联网上的另一张图片,它显示了倒置是如何发生的:
基本上,您所做的是声明您的“依赖关系”层所需的接口(在同一层中),然后在“更远”的另一个层中实现它。这个外层大致对应于“框架和驱动程序”循环;您的snbl
组件将在那里实现,在那里它将再次直接引用OkHttp
。
最后,我想承认,这是(除非我大错特错)博士布朗在他自己的回答中说得更简洁了(至少在关键点上是如此)。
发布于 2017-08-22 04:01:04
你基本上有两种选择:
SNBL
部分“停靠”到不同的服务,因此服务只依赖于接口,而不是直接依赖于SNBL
。如果您愿意,您可以将SNBL
部件单独放在一个圆圈中,在您放置服务的环和OkHttp
居住的环之间。SNBL
声明为服务所在的同一圈的一部分。它可能不是严格意义上的“业务逻辑”,但它可能是其他地方不需要的支持功能,因此“最佳”位置可能仍然是业务逻辑层。这使您可以选择省略DI。https://softwareengineering.stackexchange.com/questions/356080
复制