设计: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; }
}
课堂上的例子代表了学校、学生、学生的基本要素——决定了国家的地位。
想象一下,如果你想改变一下我们常用的特性,例如,促进邻近系列的发展。嵌套模型 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);
}
...
}
认识到两个班级之间的关系是简单的,我们的班级是学生的“服务”,改变了自己的状态,并在基础上坚持下去。
熟悉。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)
...
}
修复此问题,然后再为学生提供服务,验证其属性,并持续在数据库中。
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)
...
}
我们是学生的一个改变,介绍了对学生的响应服务的新方法,但没有最后的内容,一个代表学生的服务的班级学生专有课。您可以做一些与学生有关的操作,以代表学生参加会议,这是我们的目标。
考虑到实际情况,我们考虑到了各种因素。一些神秘的问题会在应用程序中呈现严重的错误:没有保证,在最初的时间里,一致。
现在,作为学生的公共财产,可以进行修改和修改,但学生可以直接进入学生的实例,改变自己的状态,最终改变现状。
修复逻辑重复问题的问题,并在学生中进行操作,对自己的数据进行全面的验证,并在 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; }
}
一个简单的学生神秘必需品,要建立多米尼奥模型,就必须将其与应用程序相结合 -- 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; }
}
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。系统中的模型如下:
- 一切都已经过去了。您好,我们将特别确定最终的结果,并且不会进一步发展。
- Tem um ciclo de vida curto。您可能会发现,无论节奏如何,都不能发送徽标。
- Destinam-se apenas a CRUD(创建、读取、更新、删除)。
嵌套场景、简单快速的发展、模型解决方案、最初的复杂模型和对立模型、多米尼奥模型、演示或图形显示:
修复重要信息中的嵌套图形:
- 模型是一种初始简化的复合体模型,可以在进化系统中进行医疗爆炸。如果你的系统是渐进的,你的节奏是快进的,这是介绍节奏功能渐进的一个困难。
- 另一种模式是一种复杂的模式,一种复杂的模式,一种复杂的模式,一种没有节奏的分类单元,龙卷风或新发展的特点是复杂的。
重要的是!模型是程序性的,与功能模块相关的服务,以及与数据模型相关的类。 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++;
}
与前面的模型相关的重要事项不同。最初,最重要的是,在集会中,我们要与学生的逻辑相关的歌剧,即学生本身的班级,而不是学生服务中心。不同之处代表了我们的优势,我们作为歌剧和系统的集中力量,在两个或多个班级中分布,并以逻辑为导向,以方便识别。
与我们的私人模型构建者的感知不同,我们可以通过以下方法来实现实例:创建方法,接收与学生相关的提示。 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}";
}
修复此问题,如果您想更改学生的姓名,请按照以下方法更新姓名,然后将学生姓名和属性添加到该名称中,以验证姓名的价值并重复使用,确保学生姓名一致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
};
}
快点!一部分是对学生的要求,最后是对学生的改变的要求,最后是通过 Web API 提出学生的实际情况,模型的全部分离统治和应用程序,onde esta conhece nosso modelo Student,mas o inverso não acontece。 Temos,portanto,是应用程序的 domínio desacoplado 模型。
结论
如果你想实现这一目标,那么你就可以在简单的系统中实现多种模式,并在快速的生活中获得更快的速度,从而在复杂的系统中发挥潜力。在不同的系统中,不同的模型存在不同的错误,这些错误可能与国家的模型和国家不一致的情况有关。节奏、逻辑的复制、统治模型的应用以及随之而来的变化,都是系统管理的潜在潜力。我们精确地回答了有关美国统治模型的问题。
当然,重要的是,我们要对本模型的初始复杂性进行实质性的改进,以实现本模型的一致性和最终效果。这是一个没有任何图形说明的综合体,因此我们建议您使用系统综合体,为您的客户模型带来好处!
注意:如果您熟悉 DDD,则可以修复StudentName、Age和Grade,并与 Value Objects 一起使用,也可以与Student和Entity一起使用。
我们不希望 DDD 嵌套在其中,但我们假装在算法中没有未来,它说明了 DDD 的美好前景和模式的结尾。
戈斯图?我将指示你的军刀。杜维达斯?我将发表评论。
对于服装,请从Github 的存储库中获取演示嵌套的代码。观察:与前部相反,这不是全部功能。您可以完成实施和测试! :)
再吃一个!
文章来源:https://dev.to/wsantosdev/design-modelos-anemicos-e-modelos-ricos-4k8f