具有功能的清洁架构UseCases vs Controller

时间:2019-06-18 17:15:29

标签: design-patterns controller clean-architecture

我刚刚开始阅读干净的体系结构,并且对用例实现的定义感到困惑。

考虑一个控制器类,该类具有一组在执行某些逻辑后接受T并返回R的函数

interface IController {
   fun usecase1(param:T) : R 
   fun usecase2(param:T) : R
}

现在我可以使用IController实例执行用例了。

另一种方法是将每个用例定义为一个类,并注入其他需要该功能的对象。

class UseCase1 {
    fun execute(param:T):R {}
}

class UseCase2 {
    fun execute(param:T):R {}
}

将用例作为单独的单元与将其用作某种类的功能之间的优点/缺点是什么?

IMO,  单独的单元会增加构造和注入开销  而其他方法则面临“继承问题而不是组成问题”。哪个是正确的方法?

3 个答案:

答案 0 :(得分:2)

  

将用例作为单独的单元与将其用作某种类的功能之间的优点/缺点是什么?

如果将所有内容都放在控制器中,则会违反单一责任原则。控制器代码的更改将不同于用例代码。

例如控制器通常在演示者的帮助下,从用户那里获取输入并为用户创建输出。这意味着它从视图模型读取输入并更新视图模型。视图模型属于UI,并且会由于UI原因而更改。

如果您要实现简洁的体系结构,则用例不得依赖于UI,它们的使用原因将不同于UI。这些用例与UI无关。这还将使它们更易于测试,并且可以更容易地与其他UI重复使用。

  

考虑一个控制器类,该类具有一组在执行某些逻辑后接受T并返回R的函数

请记住,控制器的参数和返回类型与用例的类型不同。

您的控制器可能使用为json序列化和反序列化而创建的类型。那是运输问题。用例不在乎传输。数据的传输方式非常详细。网络是一个细节。如果对控制器和用例使用相同的类型,则会在它们之间创建依赖关系。

答案 1 :(得分:1)

根据接口隔离原则,最好为每种情况使用单独的用例接口。它允许您以某种方式抽象用例实现。您可以独立于Controller层拆分或划分用例的实现。

我会建议将每个用例拆分为单独的类。因为当您修改其中一个时,您将100%确保不刹车另一个。 但是,如果您有大量用例,并且它们很小,那么在这种情况下,将其组合到文件中是很有意义的。但是我认为高阶函数比一类函数更适合。

在具有状态和行为的情况下创建类是有意义的,但是如果为用例创建类,则它将是无状态的,并且方法之间几乎没有密切的联系。

但是,根据干净的体系结构,真正重要的是将各层分开。如何组织存储用例并不重要,但以后有可能独立于其他层更改决策而变得至关重要。

答案 2 :(得分:1)

Clean Architecture是一种层之间耦合较少的模型。现在,当我们尝试将干净的架构应用于Google相册等网络应用程序时,它可能会具有多个层次,

  1. UI层(用户可以感知的一层)
  2. 路由层,可以将URL路由到正确的类文件
  3. 根据使用情况,可能会有多个适配器层
  4. 可以再次归类为持久层的持久层

    4.1。元数据持久性(Ex; Postgress,MySQL)

    4.2。内容持久性(Ex; Hadoop)

用例在这里如何体现?

用例是描述用户在系统上的交互的用例。这可以很简单,例如在身份验证期间针对错误的密码进行验证(或提供用于对图片应用滤镜的选项)。实现用例可能以某个方法结束,或者可能在多个类和文件之间产生。

清洁体系结构是一种准则,它坚持要求我们在各层之间进行松散耦合,以便以最小的更改即可轻松地用另一层替换一层。