设计:Modelos Anêmicos 和 Modelos Ricos

2025-06-07

设计:Modelos Anêmicos 和 Modelos Ricos

嗨!

在系列设计之后,我假装探索了与相关相关的软件设计方面,并决定了应用程序的谣言。 E,neste artigo,falaremos sobre umspecto já bastante discutido e ainda polêmico:modelos anêmicos。

什么模型是 Anêmicos

在简单的形式中,模型的形式是多学科模型的形式,它包含在不同的类别中,以呈现不同的形式或组合。在 C# 中,我们可以使用常用的属性、常见的 getter 和 setter、第二级、“serviço”的基本属性,以及初级的属性。

以下是我们的例子:

public class Student
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public byte Age { get; set; }
    public byte Grade { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

课堂上的例子代表了学校、学生、学生的基本要素——决定了国家的地位

想象一下,如果你想改变一下我们常用的特性,例如,促进邻近系列的发展。嵌套模型 teríamos algo como o código abaixo:

public class StudentService
{
    private readonly IStudentRepository _repository;
    ...
    public void Approve(Guid id, byte grade)
    {
        var student = _repository.GetById(id);
        student.Grade++;
        student.Age++;
        _repository.Update(student);
    }

    public void Reprove(Guid id)
    {
       var student = _repository.GetById(id);
       student.Age++;
       _repository.Update(student);
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

认识到两个班级之间的关系是简单的,我们的班级是学生的“服务”,改变了自己的状态,并在基础上坚持下去。

熟悉。Não?

集市,想象一下新的地籍。特里亚莫斯或后续:

public class StudentService
{
    private readonly IStudentRepository _repository;

    public void Create(Student student)
    {
        if (string.IsNullOrWhiteSpace(student.Name))
            throw new ArgumentException("Invalid name. A student name must be provided.", nameof(student.Name));

        if (student.Name.Length > 100)
            throw new ArgumentException("Invalid name. A valid name should be at maximum 100 characters long.", nameof(student.Name));

        if (student.Age < 6)
            throw new ArgumentException("Invalid age. The minimum age to a student is 6 years old.", nameof(student.Age));

        if (student.Grade < 1)
            throw new ArgumentException("Invalid grade. A student must at least at the first grade.", nameof(student.Grade));

        if (student.Grade > 9)
            throw new ArgumentException("Invalid grade. A last grade possible for a student is the ninth.", nameof(student.Grade));

        student.Id = Guid.NewGuid();
        _repository.Create(student);
    }

    ...
    public void Approve(Guid id, byte grade)
    ...
    public void Reprove(Guid id)
    ...
}
Enter fullscreen mode Exit fullscreen mode

修复此问题,然后再为学生提供服务,验证其属性,并持续在数据库中。

E,就我们的例子而言,想象一下阿鲁诺的名字精确地改变了阿尔古玛拉扎奥。特里亚莫斯或后续:

public class StudentService
{
    private readonly IStudentRepository _repository;

    public void Create(Student student)
    ...
    public void UpdateName(Guid id, string name)
    {
       var student = _repository.GetById(id);
       if(string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("Invalid name. A student name must be provided.", nameof(name));

       student.Name = name;
       _repository.Update(student);
    }
    ...
    public void Approve(Guid id, byte grade)
    ...
    public void Reprove(byte id)
    ...
}
Enter fullscreen mode Exit fullscreen mode

我们是学生的一个改变,介绍了对学生的响应服务的新方法,但没有最后的内容,一个代表学生的服务的班级学生专有课。您可以做一些与学生有关的操作,以代表学生参加会议,这是我们的目标。

考虑到实际情况,我们考虑到了各种因素。一些神秘的问题会在应用程序中呈现严重的错误:没有保证,在最初的时间里,一致

现在,作为学生的公共财产,可以进行修改和修改,但学生可以直接进入学生的实例,改变自己的状态,最终改变现状。

修复逻辑重复问题的问题,并在学生中进行操作,对自己的数据进行全面的验证,并在 100 个字符上进行验证。 Lembrando que estamos atuando em uma implmentação simples.想象一下,将主要模型复制到主要模型并进行访问和修改!

:修复、重新命名、重新验证或补充正确的名称,而不是更新名称的方法。示例是逻辑和潜在能力的重复:在某些重要部分中,可能会被忽视,模型的变化会导致错误 - 嵌套的情况下,不会限制 100 个字符基地的dados,uma excelceção lançada。

Uma outra desvantagem deste modelo é a trend a coplamento e/ou vazamento de domínio .您可以将 domínio 模型作为一系列说明,就像世界外部一样,也可以通过精确的算法来实现隐秘性,并通过应用程序来实现直接的隐秘性。举例:

public class Student
{
    [JsonIgnore]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public byte Age { get; set; }
    public byte Grade { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

一个简单的学生神秘必需品,要建立多米尼奥模型,就必须将其与应用程序相结合 -- Neste caso,via Json -- acaba sendo contaminado por um detalhe do que deveria estar restrito à camada de应用系统。

通过 Web API 的速度、模型和使用方式,可以使用学生精确的泥浆属性,并可以使用 Web API。

想象一下,如果学生需要在自己的名字和名字中分开,那么在内部系统中使用自己的名字(例如佩雷拉,阿尔贝托),就可以通过 Web API 来展示学校的应用程序。

O código deveria passar a ser o seguinte:

public class Student
{
    [JsonIgnore]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public byte Age { get; set; }
    public byte Grade { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Neste caso,em nossa API hipotética,quebraríamos nosso contrato com o app,que passaria a exibir apenas o primeiro nome do aluno no lugar do nome completo,já que o atributo Name teve seu significado alterado。

废墟模型有何意义?

回复:não necessariamente。系统中的模型如下:

  1. 一切都已经过去了。您好,我们将特别确定最终的结果,并且不会进一步发展。
  2. Tem um ciclo de vida curto。您可能会发现,无论节奏如何,都不能发送徽标。
  3. Destinam-se apenas a CRUD(创建读取更新删除)。

嵌套场景、简单快速的发展、模型解决方案、最初的复杂模型和对立模型、多米尼奥模型、演示或图形显示:

修复重要信息中的嵌套图形:

  1. 模型是一种初始简化的复合体模型,可以在进化系统中进行医疗爆炸。如果你的系统是渐进的,你的节奏是快进的,这是介绍节奏功能渐进的一个困难。
  2. 另一种模式是一种复杂的模式,一种复杂的模式,一种复杂的模式,一种没有节奏的分类单元,龙卷风或新发展的特点是复杂的。

重要的是!模型是程序性的,与功能模块相关的服务,以及与数据模型相关的类。 Ora,se operamos em um paragrapha orientado a objetos(como com C#,一种与 qual falamos aqui 相关的语言),是否可以利用 outro范例a para desenvolver nossas aplicações?

到目前为止,作为演示的任务演示了 aqui sobre modelos anêmicos,qualternativa temos para contorná-las?

使用 Ricos 模型

模型主要是指对象的程序设计原则,即定义对象模型的类,以实现对象的建立(场地和属性)和组合(方法和事件)。您可以使用各种模型、概念、定义、说明和语言范式的应用(我们是 C#)。

但是,使用该模型的技巧,可以解决在模型中出现问题的问题,并且可以解决主要的复杂问题。

Vejamos em mais detalhes abaixo:

public class Student
{
    public Guid Id { get; private set; }
    public StudentName Name { get; private set; }
    public Age Age { get; private set; }
    public Grade Grade { get; private set; }

    private Student() {}

    public static Student Create(StudentName name, Age age, Grade grade)
    {
        return new Student
        {
            Id = Guid.NewGuid(),
             Name = name,
             Age = age,
             Grade = grade
        };
    }

    public void UpdateName(StudentName name) => 
        Name = name;

    public void Approve()
    {
        Grade++;
        Age++
    }

    public void Reprove() =>
        Age++;
}
Enter fullscreen mode Exit fullscreen mode

与前面的模型相关的重要事项不同。最初,最重要的是,在集会中,我们要与学生的逻辑相关的歌剧,即学生本身的班级,而不是学生服务中心。不同之处代表了我们的优势,我们作为歌剧和系统的集中力量,在两个或多个班级中分布,并以逻辑为导向,以方便识别。

与我们的私人模型构建者的感知不同,我们可以通过以下方法来实现实例:创建方法,接收与学生相关的提示。 Ao mesmo tempo, 龙卷风作为属性做模型只读,removendo os setters。 Essa 组合了实例的关键部分、设置器的属性或部分以保证模型的一致性:封装

您必须确保自己的模型不属于学生的专有模型,不可侵犯其他班级的部分内容。学生必须按照公共决定的方法行事,并承担保证一致性的责任。

为此,我们可能会介绍学生的新技巧,并以这些技巧为范例,保证不重复商业逻辑。 Vejamos um example,一个类StudentName

public struct StudentName
{
    public string Name { get; private get; }
    public string Surname { get; private get; }

    public static StudentName Create (string name, string surname)
    {
        if(string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(surname))
            throw new ArgumentException("Invalid name. A student name and surname must be provided.");

        if(name.Length + surname.Length > 100)
            throw new ArgumentException("Invalid name. A valid name should be at maximum 100 characters long.");

        return new StudentName
        {
            Name = name,
            Surname = surname
        };
    }

    public static implicit operator string(StudentName studentName) =>
        $"{studentName.Name} {studentName.Surname}";
}
Enter fullscreen mode Exit fullscreen mode

修复此问题,如果您想更改学生的姓名,请按照以下方法更新姓名,然后将学生姓名和属性添加到该名称中,以验证姓名的价值并重复使用,确保学生姓名一致Criação、evitando assim 或 risco de Haver duplicação、neste caso、dois comportamentos distintos sobre um mesmo dado em different pontos do codigo。

注意:我们的 Github 存储库通常是这样的,但最后的文本链接却是这样的。

更... 更矛盾?

请注意,我们必须保证与我们的模型保持一致,不能解决各种问题以及应用程序的问题。但是,如果您更改了模型,则 Web API 可能会受到影响。

Vamos 解析器出现问题的解决方法:

public record CreateStudentRequest(string Name, byte Age, byte Grade);
public record UpdateStudentNameRequest(string Name, string Surname);

public record StudentModel
{
    public string Name { get; private set; }
    public byte Age { get; private set; }
    public byte Grade { get; private set; }

    public static explicit operator StudentModel(Student student) =>
        new StudentModel
    {
        Name = student.Name,
        Age = student.Age,
        Grade = student.Grade
    };
}
Enter fullscreen mode Exit fullscreen mode

快点!一部分是对学生的要求,最后是对学生的改变的要求,最后是通过 Web API 提出学生的实际情况,模型的全部分离统治和应用程序,onde esta conhece nosso modelo Student,mas o inverso não acontece。 Temos,portanto,是应用程序的 domínio desacoplado 模型。

结论

如果你想实现这一目标,那么你就可以在简单的系统中实现多种模式,并在快速的生活中获得更快的速度,从而在复杂的系统中发挥潜力。在不同的系统中,不同的模型存在不同的错误,这些错误可能与国家的模型和国家不一致的情况有关。节奏、逻辑的复制、统治模型的应用以及随之而来的变化,都是系统管理的潜在潜力。我们精确地回答了有关美国统治模型的问题。

当然,重要的是,我们要对本模型的初始复杂性进行实质性的改进,以实现本模型的一致性和最终效果。这是一个没有任何图形说明的综合体,因此我们建议您使用系统综合体,为您的客户模型带来好处

注意:如果您熟悉 DDD,则可以修复StudentNameAgeGrade,并与 Value Objects 一起使用,也可以与StudentEntity一起使用。
我们不希望 DDD 嵌套在其中,但我们假装在算法中没有未来,它说明了 DDD 的美好前景和模式的结尾。

戈斯图?我将指示你的军刀。杜维达斯?我将发表评论。

对于服装,请从Github 的存储库中获取演示嵌套的代码。观察:与前部相反,这不是全部功能。您可以完成实施和测试! :)

再吃一个!

文章来源:https://dev.to/wsantosdev/design-modelos-anemicos-e-modelos-ricos-4k8f
PREV
Dino 教程 Deno 入门 最后的想法
NEXT
我编写代码文档的 3 条规则