Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 贫血领域模型:优缺点_Language Agnostic_Design Patterns - Fatal编程技术网

Language agnostic 贫血领域模型:优缺点

Language agnostic 贫血领域模型:优缺点,language-agnostic,design-patterns,Language Agnostic,Design Patterns,我想知道使用贫血领域模型的利弊(见下面的链接) 在我看来,福勒的主要反对意见是,从以下意义上讲,ADM不是OO。如果一个人“从头开始”围绕被动数据结构设计一个系统,而被动数据结构是由其他代码段操纵的,那么这显然更像是过程设计,而不是面向对象的设计 我建议至少有两种力可以产生这种设计: 仍然认为需要在面向对象的环境中工作(或假设他们可以…)以生成新系统的设计师/程序员,以及 开发人员致力于将类似“face”的服务放在以非面向对象方式设计的遗留系统上(不考虑语言) 例如,如果要构建一组服务来公开现有

我想知道使用贫血领域模型的利弊(见下面的链接)


在我看来,福勒的主要反对意见是,从以下意义上讲,ADM不是OO。如果一个人“从头开始”围绕被动数据结构设计一个系统,而被动数据结构是由其他代码段操纵的,那么这显然更像是过程设计,而不是面向对象的设计

我建议至少有两种力可以产生这种设计:

  • 仍然认为需要在面向对象的环境中工作(或假设他们可以…)以生成新系统的设计师/程序员,以及


  • 开发人员致力于将类似“face”的服务放在以非面向对象方式设计的遗留系统上(不考虑语言)

  • 例如,如果要构建一组服务来公开现有COBOL大型机应用程序的功能,则可以根据概念模型定义服务和接口,该概念模型不反映内部COBOL数据结构。但是,如果服务将新模型映射到遗留数据以使用现有但隐藏的实现,那么新模型很可能在Fowler的文章中是“贫乏的”——例如,一组没有实际行为的TransferObject样式定义和关系

    这种折衷很可能在理想的纯OO系统必须与现有的非OO环境交互的边界上很常见。

    an是一种反模式。反模式没有优点。

    优点:

    • 你可以声称它是一个域模型 并向您的开发人员朋友吹嘘 把它写在你的简历上
    • 它很容易自动生成 从数据库表
    • 它映射到数据传输对象 出人意料地好
    缺点:

    • 您的域逻辑存在于某个地方 否则,可能是在一个充满 类(静态)方法。或者你的GUI 代码。或者在多个地方,都有冲突的逻辑
    • 这是一种反模式,所以其他 开发者会问你 理解对象的概念 面向对象的设计
    “这是一种反模式,因此其他开发人员会问您是否理解面向对象设计的概念。”

    “贫血领域模型是一种反模式。反模式没有好处。”

    贫血领域模型是否是一种反模式是一个意见问题。MartinFowler说是的,许多从内到外了解OO的开发人员说不是。 把意见说成事实很少有帮助

    但是,即使它被普遍认为是一种反模式,它仍然有一些(尽管相对较小)的好处。

    “开发人员正在努力将类似“face”的服务放在以非面向对象方式设计的遗留系统上(无论语言如何)。”


    如果您想到许多LOB应用程序,这些遗留系统通常不会使用与您相同的域模型。贫血域模型通过在服务类中使用业务逻辑来解决这个问题。您可以将所有这些接口代码放在您的模型中(在传统的OO意义上),但您通常会失去模块性。

    这与大多数反模式的优点相同:它允许您让很多人长时间忙碌。当管理者管理更多的人时,他们往往会得到更多的报酬,因此有一种强烈的不改进的动机。

    由于“贫血领域模型”是反模式的,为什么会有这么多系统来实现这一点

    我认为有几个原因

    1。系统的复杂性

    在一个简单的系统中(这几乎是您在internet上找到的所有示例和示例代码),如果我想实现:

    向订单添加产品

    我把这个函数放在订单上

    public void Order.AddOrderLine(Product product)
    {
        OrderLines.Add(new OrderLine(product));
    }
    
    很好,超级面向对象

    现在让我们假设我需要确保我需要验证产品是否存在于库存中,如果不存在,则抛出异常

    我真的不能再下订单了,因为我不希望我的订单依赖于库存,所以现在它需要继续服务

    public void OrderService.AddOrderLine(Order order, Product product)
    {
        if (!InventoryService.Has(product)
           throw new AddProductException
    
        order.AddOrderLine(product);
    }
    
    我还可以将IInventoryService传递给Order.AddOrderLine,这是另一个选项,但这仍然使订单依赖于InventoryService

    Order.AddOrderLine中仍然有一些功能,但通常它仅限于Order范围,而根据我的经验,有很多业务逻辑超出了Order范围

    当系统不仅仅是基本的CRUD时,您将以OrderService中的大部分逻辑和很少的顺序结束

    2。开发者对OOP的看法

    互联网上有很多关于哪些逻辑应该在实体上进行的激烈讨论

    差不多

    命令,保存

    秩序是否应该知道如何拯救自己?假设我们有这样的存储库

    现在可以添加订单行了吗?如果我试图用简单的英语来理解它,它也没有真正意义。用户将产品添加到订单中,我们也应该这样做User.AddOrderLineToOrder()?这似乎太过分了

    OrderService.AddOrderLine()怎么样。现在有点道理了

    我对OOP的理解是,对于封装,将函数放在类上,函数需要访问类的内部状态。如果我需要访问Order.OrderLines集合,我会将Order.AddOrderLine()放在Order上。这样类的内部状态就不会暴露

    3。国际奥委会集装箱

    使用IoC容器的系统通常是完全贫血的

    这是因为您可以测试具有接口的服务/存储库,但无法(轻松地)测试域对象,除非您将接口放在所有这些对象上

    由于“IoC”目前被誉为解决所有编程问题的解决方案,许多人盲目地遵循它,最终导致领域模型贫乏