C# - Usando uma Entity Base Class
Hoje veremos o conceito de Entity Base Class e sua utilização na linguagem C#. |
A idéia de criar uma classe base para compartilhar recursos comuns entre várias entidades de domínio é um princípio do Domain Drive Design ou DDD, e, é uma boa ideia, pois permite reunir a lógica comum em um só lugar.
Se você não conhece este conceito deixe-me apresentá-lo com um exemplo bem simples.
Vamos criar uma aplicação Console do tipo .NET Core no VS 2019 Community chamada C_EBaseClass1.
Vamos focar no modelo de domínio onde temos definidas as seguintes classes:
Nota: Vou simplificar a definição das entidades pois o objetivo é mostrar o conceito da Entity Base Class
Abaixo temos a definição de cada uma dessas entidades do modelo de domínio:
public class
Cliente { public Guid Id { get; set; } public string Nome { get; set; } public string Endereco { get; set; } } |
public class Pedido { public Guid Id { get; set; } public Guid ClienteId { get; set; } public DateTime Data { get; set; } } |
public class Item { public Guid Id { get; set; } public Guid PedidoId { get; set; } public Guid ProdutoId { get; set; } } |
public class
Produto { public Guid Id { get; set; } public string Nome { get; set; } public decimal Preco { get; set; } } |
public class
Categoria { public Guid Id { get; set; } public string Descricao { get; set; } } |
Observe que todas as entidades possuem em comum a definição da propriedade Id que é usada para identificar a entidade de forma única. O tipo usado aqui pode variar mas vamos adotar para este exemplo o tipo Guid para todas as propriedades Id.
Aqui podemos criar uma Entity Base Class ou uma classe base de entidade onde vamos definir a propriedade Id que é comum a todas as entidades e a seguir faremos com que as entidades herdem dessa classe base.
Como não desejamos que a classe base possa ser instanciada a Entity Base Class deverá ser uma classe abstrata.
Vamos criar uma classe chamada EntityBase conforme o código a seguir:
public abstract class EntityBase { protected EntityBase() { Id = Guid.NewGuid(); } public Guid Id { get; protected set; }
}
|
Na definição da nossa Entity Base Class - EntityBase - temos que:
Com isso podemos simplificar o código das entidades fazendo-as herdar da classe EntityBase:
public class
Cliente : EntityBase { public string Nome { get; set; } public string Endereco { get; set; } } |
public class Pedido
: EntityBase { public Guid ClienteId { get; set; } public DateTime Data { get; set; } } |
public class Item
: EntityBase { public Guid PedidoId { get; set; } public Guid ProdutoId { get; set; } } |
public class
Produto : EntityBase { public string Nome { get; set; } public decimal Preco { get; set; } } |
public class
Categoria : EntityBase { public string Descricao { get; set; } } |
E apenas para mostrar que funciona vamos criar uma instância da classe Cliente e atribuir valores às propriedades Nome e Endereco:
class Program
{
static void Main(string[] args)
{
Cliente cli = new Cliente();
cli.Nome = "Pedro da Silva";
cli.Endereco = "Rua projetada 100";
Console.WriteLine($"{cli.Id} - {cli.Nome} - {cli.Endereco}");
Console.ReadKey();
}
}
|
Note que ao criar a instância da classe o valor para Id será gerado no construtor da classe base.
Executando o projeto teremos o resultado:
É para isso que serve uma Entity Base Class e é assim que são utilizadas.
Você poderia pensar em usar uma interface como tipo de uma Entity Base Class.
Nesta abordagem podemos criar uma interface IEntityBase assim:
public interface IEntityBase
{
Guid Id { get; }
}
|
Mas seria essa abordagem uma boa ideia ?
Não, usar interfaces não seria uma boa ideia e vejamos porque:
1- Interfaces não permitem reunir nenhuma lógica, temos que implementar essa lógica e isso leva a duplicação de código. No nosso exemplo teríamos que criar a propriedade Id em todas as entidades repetindo justamente o que queríamos otimizar;
2- Usar interface não expressa o relacionamento da propriedade entre as entidades do domínio, pois quando uma classe implementa uma interface faz uma promessa sobre algumas funcionalidades;
3- As entidades do domínio devem estar conectadas à entidade base por uma relação 'é um' o que uma interface não proporciona;
Por esses motivos a melhor escolha é usar uma classe abstrata e não uma interface.
E estamos conversados.
"Porque pela graça sois salvos, por meio da fé; e isto não
vem de vós, é dom de Deus.
Não vem das obras, para que ninguém se glorie;"
Efésios 2:8,9
Referências: