Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Architecture 干净的体系结构:控制器和演示者应该始终是独立的类,或者可以是相同的类?_Architecture_Software Design_Clean Architecture - Fatal编程技术网

Architecture 干净的体系结构:控制器和演示者应该始终是独立的类,或者可以是相同的类?

Architecture 干净的体系结构:控制器和演示者应该始终是独立的类,或者可以是相同的类?,architecture,software-design,clean-architecture,Architecture,Software Design,Clean Architecture,我理解Clean体系结构中控制器和演示者的用途,我所说的不是用例应该调用控制器来呈现数据(或者,至少知道它必须调用控制器),而是假设我们以这种方式设置了应用程序的接口部分:(伪代码) 在这种情况下,我们的用例完全不知道外部循环。它实现了一个InputPort接口,以公开一个API,让外部循环调用它,并且它需要一个OutputPort(在Clean Architecture中是演示者),用于传递和“显示”结果 所以现在我们通常有: class Presenter implements Output

我理解Clean体系结构中控制器和演示者的用途,我所说的不是用例应该调用控制器来呈现数据(或者,至少知道它必须调用控制器),而是假设我们以这种方式设置了应用程序的接口部分:(伪代码)

在这种情况下,我们的用例完全不知道外部循环。它实现了一个InputPort接口,以公开一个API,让外部循环调用它,并且它需要一个OutputPort(在Clean Architecture中是演示者),用于传递和“显示”结果

所以现在我们通常有:

class Presenter implements OutputPort {
    + present(response: Response) {
        ...
    }
}

class Controller {

    - presenter: Presenter;

    + executeUseCase() {
        data: InputData = ...
        useCase: UseCase = UseCase(presenter)
        useCase.run(data)
    }
}
为什么我不能这样做

class Controller implements OutputPort {

    + present(response: Response) {
        ...
    }

    + executeUseCase() {
        data: InputData = ...
        useCase: UseCase = UseCase(this)
        useCase.run(data)
    }
}
这只是为了SRP的目的还是有其他原因?假设controller和Presenter足够短,并且使用相同的对象,那么在代码需要拆分之前,在单个类中维护这两个实现是否更有价值

我的意思是,每次我们谈论干净的体系结构时,我们通常会想到web应用程序或移动应用程序,在这些应用程序中,与外部世界的交互始终是用户和UI,因此在这种情况下,很明显,保持两个类分开是一种好处。 但是假设外部参与者是一个外部API,它可以发送一个信号来通知我们执行一个操作,并且应该根据执行的操作接收信号。 在这种情况下,如果我创建一个单独的控制器和演示者,我应该同时提供对外部API的引用:控制器让他监听信号并触发用例,演示者让他在用例结束时向API发送信号。
考虑到这种交互的简单性,让控制器和演示者是同一个类并不更好(尽管仍然实现了一个单独的接口,以允许将来拆分)为了避免在应用程序中传播有关外部API的知识?

首先,您的依赖关系在这两种情况下都符合干净的体系结构

假设controller和Presenter足够短,并且使用相同的对象,那么在代码需要拆分之前,在单个类中维护这两个实现是否更有价值

你可以这样做,但是如果你把两者分开,它们可能更容易测试。因为当您想要测试演示者逻辑时,不需要设置控制器的依赖项,反之亦然

我的意思是,每次我们谈论干净的体系结构时,我们通常会想到web应用程序或移动应用程序,在这些应用程序中,与外部世界的交互始终是用户和UI,因此在这种情况下,很明显,保持两个类分开是一种好处。但是假设外部参与者是一个外部API,它可以发送一个信号来通知我们执行一个操作,并且应该根据执行的操作接收信号

如果使用演示者,通常需要处理用户界面,但演示者的概念更为一般

如果控制器被其他外部系统调用。这个系统还需要一些格式的数据。可能是二进制格式,但可能是XML或JSon。在所有情况下,您都必须处理用例输出向外部呈现方式的转换。因此,演示者不一定是UI组件

因此,术语presenter、serializer或formatter都基于相同的概念。如果你在自己的类中分离它,你可以很容易地测试它

下面是我绘制的图,它展示了如何在消息传递环境中应用干净的体系结构。例如JMS。如果外部绝对不是用户界面,这将是一个体系结构。当然,MessageProducer应该使用presenter或serializer或您称之为的任何东西来创建传出消息。这是一幅旧画。也许有一天我会改变它


只要您遵守干净体系结构的依赖性规则,您就可以轻松地替换向外部展示用例的方式。

谢谢。“你可以这样做,但如果你把两者分开,它们可能更容易测试”是我希望听到的。我的意思是,如果只使用一个类实现Presenter和Controller不会产生其他副作用,很明显,这两个接口是不同的,那么我可以保持这种情况,直到测试一个接口因为另一个接口而变得困难。或者,如果要在其他地方重用Presenter,必须将它们分开。当然,只有当演示者依赖于结构化的UI模型而不是UI结构本身时,这才有效。但我想你已经考虑过了,当然。这就是为什么我在那里使用演示者!
class Controller implements OutputPort {

    + present(response: Response) {
        ...
    }

    + executeUseCase() {
        data: InputData = ...
        useCase: UseCase = UseCase(this)
        useCase.run(data)
    }
}