标签: clean-architecture

清洁架构:结合交互者

我最近偶然发现了Bob叔叔的Clean Architecture,我很想知道Interactors是否可以执行其他Interactors.

例如,截至目前,这些是我的Interactors:getEmptyAlbums,getOtherAlbums.两者都具有分别以Album列表(Album模型的ArrayList)返回的Callback.

我是否允许有一个名为getAllAlbums的Interactor在其运行块中执行前两个Interactors?

@Override
public void run() {
    getEmptyAlbums.execute();       
}

void onEmptyAlbumsReceived(ArrayList<Album albums){
     getOtherAlbums.execute;
}
void onOtherAlbumsReceived(ArrayList<Album albums){
         mMainThread.post(new Runnable() {
         callback.onAlbumsReceived(albums);
     }
});
Run Code Online (Sandbox Code Playgroud)

java android clean-architecture

10
推荐指数
3
解决办法
1010
查看次数

清洁架构 - 如何解决数据库事务?

在"干净架构"中,交互者(用例)负责定义业务逻辑.大多数示例以这种方式定义用例:

public MyUseCase() {

  public boolean execute(...) {
    int id = repository.insert(a)
    if(id > 0) {
      b.aId= id;
      repository.insert(b);
      ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Interactors主要使用简单的CRUD操作或存储库查询.上面的示例在简单的情况下是同步的,但您可以使用异步解决方案(如回调或rxjava)以相同的方法找到repos.

但是用例不完整呢?例如,您不能100%确定插入后a它仍然会在插入时存在b.如果在插入后,a你得到一些RepositoryException同时插入b.

我到目前为止看到的所有回购都没有考虑到,所以我的问题是:

清洁架构中上述问题的解决方案是什么?

clean-architecture interactors

10
推荐指数
1
解决办法
793
查看次数

Python 中的工厂方法与注入框架 - 什么更干净?

我通常在我的应用程序中做的是使用工厂方法创建我所有的服务/dao/repo/clients

class Service:
    def init(self, db):
        self._db = db

    @classmethod
    def from_env(cls):
        return cls(db=PostgresDatabase.from_env())
Run Code Online (Sandbox Code Playgroud)

当我创建应用程序时

service = Service.from_env()
Run Code Online (Sandbox Code Playgroud)

什么创建了所有依赖项

在我不想使用真实数据库的测试中,我只做 DI

service = Service(db=InMemoryDatabse())
Run Code Online (Sandbox Code Playgroud)

我想这与干净/十六进制架构相去甚远,因为 Service 知道如何创建数据库并知道它创建的数据库类型(也可能是 InMemoryDatabse 或 MongoDatabase)

我想在干净/十六进制架构中我会有

class DatabaseInterface(ABC):
    @abstractmethod
    def get_user(self, user_id: int) -> User:
        pass

import inject
class Service:
    @inject.autoparams()
    def __init__(self, db: DatabaseInterface):
        self._db = db
Run Code Online (Sandbox Code Playgroud)

我会设置注入器框架来做

# in app
inject.clear_and_configure(lambda binder: binder
                           .bind(DatabaseInterface, PostgresDatabase()))

# in test
inject.clear_and_configure(lambda binder: binder
                           .bind(DatabaseInterface, InMemoryDatabse()))
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 我的方式真的很糟糕吗?它不再是一个干净的架构了吗?
  • 使用注入有什么好处?
  • 是否值得打扰并使用注入框架?
  • 还有其他更好的方法可以将域与外部分开吗?

python architecture dependency-injection hexagonal-architecture clean-architecture

10
推荐指数
2
解决办法
1617
查看次数

Flutter/Dart:子类冻结数据类

我正在使用以下插件:https : //pub.dev/packages/freezed

我想子类化冻结的数据类以在我的数据层中提供附加功能。所以我有我的数据类,它看起来像:

import 'dart:ui';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'card.freezed.dart';

@freezed
abstract class Card with _$Card {
  factory Card({String text, Color color, List<String> categories}) = _Card;
}
Run Code Online (Sandbox Code Playgroud)

现在我想将此 Card 类作为我的 CardModel 的超类,以便 CardModel 可以访问相同的字段、copyWith 方法、值相等......但我不知道如何去做。我正在尝试这样的事情:

import 'package:flutter/widgets.dart';
import 'package:growthdeck/features/card_deck/domain/entities/card.dart';

import '../../domain/entities/card.dart';

abstract class CardModel extends Card {
  factory CardModel.fromMap(Map<String, dynamic> card) => Card(
        text: card["text"],
        color: Color(int.parse(card['color'])),
        categories: card['categories'] as List<String>,
      );
}
Run Code Online (Sandbox Code Playgroud)

这会引发以下错误:

package:growthdeck/features/card_deck/data/models/card_model.dart 11:9  new CardModel.fromMap
test/features/card_deck/data/models/card_model_test.dart 13:23          main.<fn>

type '_$_Card' is not a subtype of type …
Run Code Online (Sandbox Code Playgroud)

dart flutter clean-architecture

10
推荐指数
1
解决办法
1740
查看次数

干净的架构.演示者的工作是什么?

我一直在阅读一些关于干净架构的文章,以及它如何在android中实现.我看到了显示其Android实现的示例应用程序.另外,我在Android上对Clean架构进行了很好的讨论

所以,我对大多数概念都有所了解,但我希望能够对某些事情有所了解.

根据我的理解,

  • View层是处理UI和框架相关内容的外层
  • 演示者是视图的直接通信器,它接受用户输入,并通过将其传递给用例层或交互器层来执行基于此的某些用例.
  • Interactor执行用例,将其返回给演示者发送的回调,
  • Presenter再次将此结果转换为视图可理解的数据结构(ViewModel),并将其传递回视图.

我没有列出关于内层如存储库的更多细节,因为我的问题与上述步骤有关

在这里,演示者是否只能充当UseCases和UI之间的中介,作为数据调度员?

是否仅使用视图模型来使用案例模型转换,反之亦然?

输入验证逻辑依赖于哪一层?可以在演示者里面吗?例如,如果我们采用注册过程的小用例,

一旦用户输入了详细信息并单击了注册按钮,并将数据发送给演示者,就好了

  • 如果有任何错误通知视图,Presenter将验证输入值
  • 如果值正确,则将其转换为用例模型,并执行某个用例,一旦交互器给出结果,再次转换为视图模型,将其发送到视图.

第二个问题是,谁控制导航?View或Presenter或UseCase?

谁决定下一步去哪儿?

例如 - 考虑登录过程的用例,用户将在其中输入凭据并单击"确定".

成功登录后,

  • 如果未验证用户电子邮件,请转到电子邮件验证屏幕
  • 如果用户配置文件未完成,请设置配置文件,然后仅转到主屏幕
  • 如果用户是新用户,则显示新的优惠屏幕,否则直接转到主屏幕

那么,谁负责在接下来的哪个屏幕上做出这些决定?它是演示者,它相应地决定和导航视图吗?或者是用例处理程序有责任告知演示者下一个状态是什么?

很抱歉提出这个问题的时间太长了,但我只是想详细说明我目前的理解.提前致谢

android design-patterns clean-architecture android-mvp

9
推荐指数
1
解决办法
1713
查看次数

干净的架构 - DTO 到业务模型的映射应该在哪里进行?

我有一个由存储库管理的 DTO,最后我想将此 DTO 映射到表示层使用的不同类型的对象。

映射应该发生在存储库还是域层?(用例/交互器)

clean-architecture

9
推荐指数
2
解决办法
1万
查看次数

清洁建筑设计模式

在此输入图像描述

https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

我对这种模式有一些疑问.数据库处于更高层,但实际上如何运作?例如,如果我有一个微服务,只是管理这个实体:

其中一个用例是管理人员.管理人员正在保存/检索/ ..人员(=> CRUD操作),但要做到这一点,Usecase需要与数据库通信.但这将违反依赖性规则

使该体系结构工作的首要规则是依赖规则.此规则表明源代码依赖性只能指向内部.

  1. 这甚至是一个有效的用例吗?
  2. 如果它在外层?如何访问数据库?(依赖性Iversion?)

如果我得到一个GET /person/{id}请求我的微服务应该像这样处理吗?

在此输入图像描述

但使用依赖倒置将是违反

内圈中的任何东西都不能知道外圈中的某些东西.特别是,内圈中的代码不得提及在外圈中声明的内容的名称.这包括功能,类.变量或任何其他命名的软件实体.


跨越边界.在图的右下方是我们如何穿过圆边界的示例.它显示控制器和演示者与下一层中的用例通信.注意控制流程.它从控制器开始,在用例中移动,然后在演示者中执行.还要注意源代码依赖性.他们中的每一个都指向用例.

我们通常使用依赖性倒置原则来解决这个明显的矛盾.例如,在像Java这样的语言中,我们将安排接口和继承关系,使得源代码依赖性反对跨越边界的正确点处的控制流.

例如,考虑用例需要调用演示者.但是,此调用不能是直接的,因为这会违反依赖关系规则:内圈中不能提及外圈中的名称.因此我们在内部圆圈中使用用例调用接口(此处显示为用例输出端口),并使外部圆圈中的演示者实现它.

相同的技术用于跨越体系结构中的所有边界.我们利用动态多态来创建反对控制流的源代码依赖关系,这样无论控制流向何种方向,我们都可以符合依赖关系规则.

Use Case层是否应声明将由DB Package(框架和驱动程序层)实现的存储库接口

在此输入图像描述

如果服务器收到一个GET /persons/1请求,PersonRest会创建一个PersonRepository,并将这个Repository + ID传递给ManagePerson :: getPerson函数,getPerson不知道PersonRepository但知道它实现的接口,所以它不违反任何规则吗?ManagePerson :: getPerson会使用该Repository来查找实体,并将Person Entity返回给PersonRest :: get,它会将Json Objekt返回给客户端吗?

遗憾的是英语不是我的母语,所以我希望你们能让我知道我是否理解了这种模式是正确的,也许可以回答我的一些问题.

Ty提前

java rest design-patterns microservices clean-architecture

9
推荐指数
1
解决办法
2038
查看次数

Nestjs依赖注入和DDD /清理架构

我正在尝试通过实现一个干净的架构结构来测试Nestjs,并且想验证我的解决方案,因为我不确定我是否知道执行此操作的最佳方法。请注意,该示例几乎是伪代码,并且缺少许多类型或泛型,因为它们不是讨论的重点。

从我的域逻辑开始,我可能想在类似于以下类的类中实现它:

@Injectable()
export class ProfileDomainEntity {
  async addAge(profileId: string, age: number): Promise<void> {
    const profile = await this.profilesRepository.getOne(profileId)
    profile.age = age
    await this.profilesRepository.updateOne(profileId, profile)
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我需要访问profileRepository,但是按照干净架构的原理,我现在不想为实现而烦恼,所以我为此写了一个接口:

interface IProfilesRepository {
  getOne (profileId: string): object
  updateOne (profileId: string, profile: object): bool
}
Run Code Online (Sandbox Code Playgroud)

然后,将依赖项注入到ProfileDomainEntity构造函数中,并确保它遵循预期的接口:

export class ProfileDomainEntity {
  constructor(
    private readonly profilesRepository: IProfilesRepository
  ){}

  async addAge(profileId: string, age: number): Promise<void> {
    const profile = await this.profilesRepository.getOne(profileId)
    profile.age = age

    await this.profilesRepository.updateOne(profileId, profile)
  }
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个简单的内存实现,让我运行代码:

class ProfilesRepository …
Run Code Online (Sandbox Code Playgroud)

domain-driven-design dependency-injection typescript clean-architecture nestjs

9
推荐指数
3
解决办法
2698
查看次数

如何使用Asp Net Core在Clean Architecture中实现Asp Identity

是否有关于在干净的架构中实现 asp 身份以及如何在应用程序层中使用从域层中的 IdentityUser 继承的用户实体应用 CRUD 操作的任何代码或文档我在域层中实现了 Asp 身份有什么想法吗?我忘了提到我在应用程序层使用了 CQRS

identity clean-architecture

9
推荐指数
1
解决办法
7559
查看次数

如何以干净的架构和块库 flutter 实现 WebSocket?

我正在尝试使用干净的架构在flutter中实现WebSocket,我的问题是如何从数据源获取数据,因为在使用rest API的情况下,您只需请求和等待数据并从数据层获取它,但在实时应用程序中,例如使用Web套接字如何在不请求的情况下连续返回数据,我应该将WebSocket代码放在哪一层,如何获取数据并将其发送到bloc?

websocket dart flutter clean-architecture bloc

9
推荐指数
1
解决办法
3398
查看次数