这是我第一次尝试将干净的架构原则应用于工作项目,但我遇到了许多问题。任务的本质:
有外部服务和 CRM。客户可能来自外部服务,需要转移到 CRM。如果客户已存在于 CRM 中,则需要在外部服务中检查其上次修改时间。如果更改时间与数据库中的数据不同,您需要使用客户端 ID 更新 CRM 中的信息。
我的实施问题:
对 CRM、数据库和其他外部系统运行查询的正确位置在哪里?例如,我有一个名为 ACrmClientsRepository(A 是 CRM 的常规名称)的 CRM 存储库的实现,如下所示:
class ACrmClientsRepository implements ClientsRepositoryInterface
{
public function __construct(private readonly ClientsDBInterface $clientsDB)
{
}
public function create(CreateClientDTO $createClientDTO)
{
$createdRecord = ACrmApi::getInstance()->api()->records()->createRecord('Clients', [
// ДАННЫЕ
]);
$this->clientsDB->create([
// ДАННЫЕ НА СОЗДАНИЕ В БД
]);
// ПЕРЕДАЮ ДАННЫЕ ДАЛЕЕ
}
}
我为使用外部服务制定了类似的结构。这种方法如何符合干净架构的原则?是否可以在实施中直接查询CRM和数据库?
- 我将与数据库的交互转移到单独的实现中,并将它们捆绑到 DI 容器中。例子:
public function __construct(private readonly ClientsDBInterface $clientsDB)
{
}
这是正确的方法吗?每个实现使用自己的实现来处理数据库是否正确?
实现中的逻辑(例如,if、else、switch)是否可以接受?据我了解,所有业务逻辑都应该在用例中。这是真的吗?
哪一层负责循环处理数据?我有一个任务:处理客户一圈,检查他们的更改。执行此操作的逻辑最好放置在哪一层?
客户表结构。为了最大限度地减少表的数量,我将以下字段添加到clients表中:
external_id — 来自外部系统的客户端 ID。 local_id — 当前系统中的客户端 ID。 service — 客户端来自的服务的名称。
逻辑示例:
我从 AExternalClientsRepository 接收数据。我检查客户端是否在数据库中。如果没有客户端,我会在数据库中创建一个 service = AExternal 的条目,然后通过 ACrmClientsRepository 在 CRM 中创建它,并在数据库中添加一个 service = ACrm 的新条目。这种数据结构和实现方法有多健全?