标签: hexagonal-architecture

六边形架构——一个简单的用例

我已经读了很多回合六方架构和我得到最多的概念(当然,我希望我做的),我没有找到任何例子是建筑用例的明智。

假设我的应用程序域模型是为了让人陶醉。整个业务逻辑包含在Person域层的类中。

class Person
{
    private $name;
    private $age;

    function __construct($name, $age)
    {
        $this->age  = $age;
        $this->name = $name;
    }

    public function drink()
    {
        if ($this->age < 18) {
            echo $this->name . ' cant drink';
        }

        echo $this->name . ' drinks tequila';
    }
}
Run Code Online (Sandbox Code Playgroud)

领域层还包含一个 PersonRepository

interface PersonRepository
{
    public function findPersonByName($name);
}
Run Code Online (Sandbox Code Playgroud)

实施者:

class DoctrinePersonRepository implements PersonRepository
{
    public function findPersonByName($name)
    {
        // actual retrieving
    }
}
Run Code Online (Sandbox Code Playgroud)

假设我想通过访问让一个人醉:GET /person/johnDoe/drink。我应该创建一个用例,如:

class MakePersonDrinkCase
{
    /** …
Run Code Online (Sandbox Code Playgroud)

architecture domain-driven-design n-tier-architecture hexagonal-architecture

7
推荐指数
1
解决办法
4970
查看次数

具有六边形体系结构和DCI模式的框架和数据库适配器

我尝试用Ruby设计一个基于Web的应用程序.我开发了一个简单的核心应用程序,在没有框架和数据库的六边形体系结构中实现DCI范例.核心六边形中有小六边形和网络,数据库,日志等适配器.每个六边形都没有数据库和框架.在这种方法中,如何提供与数据库独立的数据库模型和实体类的关系.我希望将来从Rails改为Sinatra或数据库.实际上,我如何实现数据库适配器或框架适配器,这是完全隔离的rails和mongodb在这个核心Hexagon中.有任何想法吗?

ruby ruby-on-rails adapter hexagonal-architecture

6
推荐指数
1
解决办法
620
查看次数

包含演示者或返回数据的用例?

考虑到 Clean Architecture定义,尤其是描述控制器、用例交互者和演示者之间关系的小流程图,我不确定我是否正确理解“用例输出端口”应该是什么。

干净的架构,如端口/适配器架构,区分主要端口(方法)和次要端口(由适配器实现的接口)。按照通信流程,我希望“用例输入端口”是一个主要端口(因此,只是一个方法),而“用例输出端口”是一个要实现的接口,可能是一个采用实际适配器的构造函数参数,以便交互者可以使用它。

举一个代码示例,这可能是控制器代码:

Presenter presenter = new Presenter();
Repository repository = new Repository();
UseCase useCase = new UseCase(presenter, repository);
useCase->doSomething();
Run Code Online (Sandbox Code Playgroud)

演示者界面:

// Use Case Output Port
interface Presenter
{
    public void present(Data data);
}
Run Code Online (Sandbox Code Playgroud)

最后,交互器本身:

class UseCase
{
    private Repository repository;
    private Presenter presenter;

    public UseCase(Repository repository, Presenter presenter)
    {
        this.repository = repository;
        this.presenter = presenter;
    }

    // Use Case Input Port
    public void doSomething()
    {
        Data data = this.repository.getData();
        this.presenter.present(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

这种解释似乎得到了前面提到的图表本身的证实,其中控制器和输入端口之间的关系由带有“锋利”头的实心箭头表示(UML 表示“关联”,意思是“有一个”,其中控制器“有一个”用例),而演示者和输出端口之间的关系由带有“白色”头的实心箭头表示(UML 表示“继承”,这不是“实现”的那个,但可能就是这样反正意思)。 …

architecture hexagonal-architecture clean-architecture

6
推荐指数
2
解决办法
2266
查看次数

DDD Hexagon - 域层在任何情况下都应该与基础设施 (DAL) 层对话吗?

据我了解,六边形架构的关键规则之一是域层​​如何与除与其一起工作的应用程序层之外的所有内容隔离(域层完全没有依赖关系,因为它位于核心):

在此输入图像描述

那么我的问题是,域层是否做过任何工作或有任何数据持久性方面的知识?假设我们有一些业务逻辑依赖于数据的检索和持久化,那么它是否应该始终应用程序层来协调?

加载业务逻辑运行所需的所有内容 -> 告诉领域层运行所有业务逻辑 -> 提取业务逻辑的结果并告诉基础设施层保存它们 ->

从这个意义上说,应用程序层不是总是需要跟踪域层计算的任何结果,因此总是会实现某种 UnitOfWork 模式来跟踪这些结果吗?

域层是否可以与存储库或存储库的接口一起使用?有一些消息来源似乎表明这很好,但从我的角度来看,这与图表完全矛盾。

architecture domain-driven-design hexagonal-architecture

6
推荐指数
1
解决办法
7337
查看次数

领域驱动设计 (DDD):领域事件处理程序 – 将它们放置在哪里?

我对在基于六边形架构的应用程序中处理域事件的位置感到困惑。我说的是有界上下文内部域事件,而不是上下文间集成/应用程序/公共事件。

背景

据我了解,应用程序逻辑(即用例逻辑、工作流逻辑、与基础设施的交互等)是命令处理程序所属的地方,因为它们特定于特定的应用程序设计和/或 UI 设计。然后命令处理程序调用域层,所有域逻辑都驻留在其中(域服务、聚合、域事件)。领域层应该独立于特定的应用程序工作流程和/或 UI 设计。

在许多资源(博客、书籍)中,我发现人们在应用程序层中实现域事件处理程序,类似于命令处理程序。这是因为域事件的处理应该在其自己的事务中完成。由于它可能会影响其他聚合,因此必须首先通过基础设施加载这些聚合。然而,关键点是:领域事件被分解并变成对聚合的一系列方法调用。这个重要的转换仅存在于应用层。

问题

我认为关于哪些领域事件会对其他聚合产生什么影响的知识是领域知识本身的一个组成部分。如果我要删除除域层之外的所有内容,那么这些知识不应该保留在某个地方吗?在我看来,我们应该将域事件处理程序直接放置在域层本身中:

  • 它们可以是域服务,接收域事件和可能受其影响的聚合,并将域事件转换为一个或多个方法调用。

  • 它们可以是聚合本身的方法,直接消耗整个域事件(即签名包含域事件类型)并对其执行任何操作。

当然,为了加载受影响的聚合,我们仍然需要在应用层有一个相应的处理程序。该处理程序仅启动一个新事务,加载感兴趣的聚合并调用域层。

由于我从未在任何地方看到过这一点,我想知道我是否对 DDD、领域事件或应用程序层和领域层之间的差异有什么误解。

编辑:示例

让我们从这种常用的方法开始:

// in application layer service (called by adapter)
public void HandleDomainEvent(OrderCreatedDomainEvent event) {
    var restaurant = this.restaurantRepository.getByOrderKind(event.kind);
    restaurant.prepareMeal(); // Translate the event into a (very different) command - I consider this important business knowledge that now is only in the application layer.
    this.mailService.notifyStakeholders();
}
Run Code Online (Sandbox Code Playgroud)

换成这个怎么样?

// in application layer service (called by adapter)
public void HandleDomainEvent(OrderCreatedDomainEvent event) {
    var …
Run Code Online (Sandbox Code Playgroud)

domain-driven-design business-logic hexagonal-architecture domain-events

6
推荐指数
1
解决办法
7103
查看次数

N层到六边形(端口和适配器)架构

Alistair Cockburn介绍了一种六角形架构,现在它被称为端口和适配器模式.在我的理解中,这个概念类似于n层架构,其中一层仅通过抽象(接口)依赖于另一层.例如,应用程序层依赖于许多存储库服务接口而不是它的实现.这里不需要单独实现端口或适配器.像Unity这样的IoC容器可以注入存储库的实现,因此不需要适配器.

我是否将此端口和适配器模式与DIP(依赖注入原则)混淆?

有人能指出我的端口和适配器模式的实现?谢谢.

n-layer hexagonal-architecture

5
推荐指数
1
解决办法
3368
查看次数

休眠业务对象可以用作干净架构中的实体吗?

在我们的项目中,我们使用 eclipse hibernate 插件生成的类进行持久化。生成的类具有以下结构。

MyClass extends BaseMyClass //POJO's, that are refenced in the hbm
files
Run Code Online (Sandbox Code Playgroud)
MyClassDAO extends BaseMyClassDAO //DAO objects that use hibernate
session objects to provide CRUD API's for working with DB
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我们使用映射文件中使用的 POJO 类作为最内层的实体,是否会违反 Uncle Bobs 的清洁架构。

在这种情况下,hibernate 特定的 DAO 类将属于最外层,而 UseCases 层将通过提供要实现的接口与该层进行通信。

java hibernate hexagonal-architecture onion-architecture clean-architecture

5
推荐指数
1
解决办法
528
查看次数

是否应该从应用程序层抛出域异常?

我正在阅读Vaughn Vernon的书-实现域驱动设计。有一个项目管理应用程序的示例。有聚合,例如BacklogItem,Sprint等。如果我在Domain层中定义了BacklogItemNotFoundException。我的Rest适配器应该抓住它并转换为NotFoundHttpResult吗?还是任何其他破碎的不变异常,例如:EmailPatternBrokenException或TooManyCharactersForNameException或应在Rest适配器(端口和适配器体系结构)中处理的任何东西,然后重新转换为Rest响应?如果是,这意味着RestAdapter应该具有对Domain层的引用?这就是困扰我的...

domain-driven-design exception-handling hexagonal-architecture

5
推荐指数
3
解决办法
1699
查看次数

用例接口(应用服务)?

在遵循具有 ddd 原则的六边形架构时,用例或应用程序服务是否应该具有接口和实现?例如,用例“删除视频”,是否应该让 IDeteVideo(接口)和 DeletVideoImpl(实现)实现该接口?

如果答案是肯定的,那么用例的接口应该在哪里,在领域层还是在应用层?很明显,实现应该总是在应用层。

我认为用例不是经常变化的东西,所以在我看来,我认为没有必要有一个接口,有实现就足够了。但是就六边形架构和 DDD 原则而言,是否对此有所说明?

提前致谢。

domain-driven-design use-case hexagonal-architecture

5
推荐指数
2
解决办法
531
查看次数

在洋葱、六边形或简洁架构中,域模型是否可以包含与数据库中的域模型不同的属性?

我问你谁知道并有使用任何分层架构(洋葱、六边形、干净等)构建软件的经验。每当我在谷歌上搜索软件架构时,人们都会有不同的观点,并以不同的方式解释相同的架构。

条款

在您阅读问题之前,有些术语可能会让您感到困惑,因此我将在下面对其进行定义。我不确定我是否对它们有“正确”的定义,但我从互联网上收集了这些信息。如果我有误解,请告诉我。

领域层:包含企业/业务逻辑并使用领域模型。位于中心并且不依赖于除领域模型之外的任何其他层。

应用层:包含应用逻辑,从基础设施层接受DTO,传递View Model

DTO(Data Transfer Object):用于在层与层之间传输数据的类、JSON字符串等。可能是一个纯数据容器。

VM(View Model):从应用层传递到表示层的DTO。

DO(Domain Model):域层使用的类、JSON字符串等。可能是一个纯数据容器。

VO(Value Object):数据库实体(一个数据库行),或者数据库使用的一种数据格式。可以从数据库层转移到应用层。

概括

在洋葱、六边形或简洁架构中,域层位于中心(即域层不依赖于域模型以外的任何层,域模型用于将数据传输到其他层或接受来自更高层的数据)。

这意味着域使用的域模型(DTO、POJO、VO 或其他)可能与数据库用于保存持久数据的模型不同。

我画了一个图表,以便我可以给你更好的解释。

在此处输入图片说明

在此处输入图片说明

第一季度

请看第二张图片的红色部分。

与传统的分层或 n 层架构不同,如果领域层位于中心,那么领域模型是否可以拥有比数据库实体(行)更多的属性(或不同的属性)?

例如,假设域层使用一个名为Person的类。用户请求所有在服务器中注册的人的照片。让我们假设数据库只包含所有人的姓名。但是,我们可能会使用其他网络服务器通过姓名请求某人的照片。所以应用层会从数据库中读取所有的名称,并通过这些名称,通过 HTTP 请求从其他 Web 服务器获取所有图片。之后,带有姓名和图片的Person列表将作为视图模型(DTO)发送给用户。

问题二

持久层可能由数据库、文件系统、其他 Web API 等组成。

表示层可以是网站、桌面应用、移动应用、Web API 等。

这两层都是基础设施层的一部分,都依赖于应用层,而应用层只依赖于领域层。

当应用层接受来自表现层的请求时,没有问题,因为表现层调用应用层,表现层知道应用层。

大多数时候,应用层需要从持久层获取数据。

应用层无法在没有任何依赖的情况下调用持久层,因为它不知道持久层中的任何类。

这就是我目前的理解,谁能给我一个清晰的解释,数据应该如何流动以及从低层到高层的通信是如何完成的?

对于那些想写代码的人,我更喜欢 C#。

software-design n-tier-architecture hexagonal-architecture onion-architecture clean-architecture

5
推荐指数
1
解决办法
1352
查看次数