根据' Uncle Bobs"《清洁建筑》;软件系统的核心由实体(关键业务规则)和用例(用例应该是一个对象)组成。用例为与实体交互的流程流建模,但是用例应该如何初始化实体对象呢?该书明确指出,不应该将实体作为输入参数传递给用例类。另一方面:如果每个用例的输入必须包含与初始化实体相关的所有数据,并且在数百个用例中重用实体,则更改实体参数可能会变得痛苦。如果我需要实体中的另一个参数,我将不得不修改使用该实体的所有用例的输入。
解决那个问题的最好方法是什么?
清洁构架
实体通常是从注入到用例中的工厂或存储库中检索的。初始化是存储库或工厂的责任,从而将其与用例解耦。
输入很少具有初始化实体所需的所有数据,仅足以从做的东西请求该实体具有所有数据。例如,主键或查找值。
例如,如果你有一个登录用例。您将接受用户名和密码进入用例。不知道如何初始化存储在数据库(或ldap、auth服务等)中的用户的所有信息。它只知道用户的登录名和建议的密码。登录用例应该与用户存储库对话,并通过该登录检索用户(不一定是主键,但仍然是唯一的,足以标识单个用户)。该存储库可以返回一个用户实体,您可以将其与密码进行比较。
以这种方式解耦意味着您可以轻松地交换存储库以拥有不同的存储,更重要的是,可以轻松地通过模拟来测试它。
用例为与实体交互的流程流建模,但是用例应该如何初始化实体对象?
用例通常根据实体对象的标识从存储库中检索实体对象,并且存储库初始化该实体。
如果每个用例的输入必须包含与初始化实体相关的所有数据,并且实体在数百个用例中被重用,则更改实体参数可能会变得痛苦。
通常很少有创建主数据的用例,例如客户或产品。这些用例的本质是,您传递给它们初始化实体所需的所有属性。之后,他们使用存储库来持久化他们创建的实体,以便其他用例稍后可以通过它们的id检索它们。
如果你有很多用例需要所有的实体数据,你可能有另一个设计问题,或者你只是有很多创建用例。
可能你正在实现一个没有真正用例的应用程序,因为它只是一个很好的数据库访问前端。在这些应用程序中,用例逻辑是由用户完成的。干净的体系结构不适合这些情况。