我一直在使用Bob叔叔的实现一个概念应用程序的示例,并且遇到了一些问题。
Bob叔叔的体系结构要求使用接口显式地分离请求和响应。这在大多数情况下都不是问题(例如,当使用MVP模式实现UI时),但我不知道如何应用它来使用Spring创建REST。
我的Controller有一个具有以下签名的方法:
Response greet(String name)映射到/greeting,它使用名称并根据名称的值输出不同的问候语。
注入到Controller中的是接收名称并创建问候语的UseCase,通过注入的OutputPort发送输出。
问题是,我不能以这种方式分离输入和输出,因为Controller需要与输入和输出交互才能创建响应。
我能想出的“实现”这个方法的唯一方法是使用InputPort返回值,这听起来很糟糕,根本不符合清洁体系结构的要求。
我一直在考虑这个问题,我无法找到我的Controller可以同时充当Controller和Presenter的任何方式。我是不是漏掉了什么?是否有更好的设计允许将REST的输入和输出分离,而不使事情变得过于复杂?
编辑:我又读了一遍“清洁架构”的第23章和第24章,我肯定可以更好地表达我的问题。我现在作为一个解决方案(工作,非常好)是一个一维边界(第219页),我想知道我是否可以把这个接口扩展到两个交互接口中。希望这能澄清我的观点。
发布于 2018-07-03 14:23:32
好吧,我想我明白了:你有一个上下文阻抗错配。
你现在在一个框架里,邦德先生。这里的游戏和构图有点不同。
识别的基本思想是:也就是说,“视图”随到达的每个HTTP请求而改变(更准确地说,它有一个范围耦合到HTTP连接的生存期,但这在这里并不重要)。
这意味着我们需要为每个请求创建一个新的作曲管道。
好消息是:春天已经在幕后为你做了这件事。
坏消息是,Spring使用的是单一的输入输出边界,而不是将它们分开。
我说的是“坏消息”,因为你正试图使这个圆钉与马丁所描述的方孔相吻合。我认为Spring在这里所做的是“好的”,只是不方便您想要的接口。
所以让我们假设:您有一个期望连接到输入边界和输出边界的用例交互器,并且您的控制器上有这个签名。这次又是什么?
Response greet(String name) {
InputBoundary in = inputBoundaryFor(name);
// Arbitrary choice
List greetings = new ArrayList();
OutputBoundary out = outputBoundaryFor(greetings);
// Here's our composition with request scope.
UseCaseInteractor uci = useCaseInteractorFor(in, out);
uci.run();
String greeting = greetings.get(0);
return responseFrom(greetings.get(0));
}如果您对UseCaseInteractor的API比较幸运,它可能会看起来像:
final UseCaseInteractor uci = ...
Response greet(String name) {
InputBoundary in = inputBoundaryFor(name);
// Arbitrary choice - any reasonable container for
// for a result could be used here.
CompleteableFuture greetings = new ArrayList();
OutputBoundary out = outputBoundaryFor(greetings);
uci.run(in, out);
String greeting = greetings.get();
return responseFrom(greetings.get(0));
}如果我们将其构造为回调,您可能会发现这更熟悉。
Response greet(String name) {
// Arbitrary choice - any reasonable container for
// for a result could be used here.
CompleteableFuture greetings = new ArrayList();
uci.run(name, (greeting) -> {
greetings.complete(greeting);
});
String greeting = greetings.get();
return responseFrom(greetings.get(0));
}但是,核心思想是,您有两个功能;在带有用例交互器的模块中,您有一个类似于
InputData -> OutputData在您的web层中,您有一个类似于
OutputData -> ViewModel输入和输出边界只是组合这两个函数的一种方式,而不引入指向错误方向的依赖关系。
https://softwareengineering.stackexchange.com/questions/373413
复制相似问题