Tag Archives: Arquitetura

Herança com C# e Entity (Code First)

C# 7 Replies

Olá novamente,

Desta vez decidi falar sobre algo que achei bem bacana e útil para o dia-a-dia: Herança com Entity.

Comumente utilizo uma tabela de abstração para Entidades de sistema e Objetos de valor. Todas as minhas tabelas são de um destes dois tipos, assim, não tenho que ficar replicando as propriedades:

Neste caso, quando eu tiver uma classe que representa uma entidade no banco, irei sempre herdar de um destes dois modelos, permitindo, assim, generalizar a utilização. Bom, para seguir este perfil, devemos mapear nossa coleção em função da classe filho, ou seja, da entidade que representa a “tabela”:

Quando a migração for efetuada, o banco refletirá a entidade User, com suas propriedades, adicionadas das propriedades de AppEntity.

Outra forma de se trabalhar é fazendo o mapeamento da maneira oposta, por exemplo, quando temos uma entidade Profile e uma especificação, como CustomerProfile. Seguindo esta lógica, a regra de negócio está voltada para Profile e CustomerProfile é apenas um desdobramento e queremos refletir isto no desenvolvimento:

Utilizando esta forma, quando o migrations gerar o banco de dados, ele criará a tabela Profiles, com uma coluna adicionada chamada Discriminator, que conterá o nome da especialização que foi adicionada.

Após este processo, a utilização do código resultante fica um pouco diferente do comum, pois a especialização CustomerProfile deverá ser acessada, para consulta, através da coleção Profiles, com o auxílio do método OfType, já a inclusão permanecerá inalterada, assim:

Assim, customerProfiles será do tipo List<CustomerProfile> e a consulta Where poderá tratar seus parâmetros de acordo com a classe CustomerProfiles.

Enfim, a herança é sempre muito bem vinda quando queremos reduzir o acoplamento do código e generalizar melhor nossas abstrações, permitindo uma melhor manutenção do nosso código e facilitando o trabalho. Lembrando que, quando estas técnicas forem utilizadas, as classes devem ter nomes que remetam à sua função, facilitando a compreensão da estrutura aplicada.

Até mais,

 

Interfaces e desacoplamento

Boas práticas 2 Replies

Olá, vamos falar um pouco de desacoplamento do código através do uso de interfaces, afinal, o acoplamento significa uma grande interdependência de código que pode causar danos na aplicação durante o processo de manutenção ou, até mesmo, quando criamos novas funcionalidades.

Mas o que é isso?

Pense que, quando você escreve uma classe e referencia, ela pode seguir o que está escrito no livro do Uncle Bob:

“Converse com amigos não com estranhos”

Devemos pensar que seus métodos podem conhecer as propriedades de seus pais e de seus amigos e, seus amigos, devem lhe ser apresentado, no nosso caso, através do contrutor e nada mais do que isso.

Quando você trabalha com desacoplamento, há conceitos para melhorar a arquitetura da aplicação, como a inversão de controle onde, as classes recebem em seus construtores o que vai ser pertinente às referências “estrangeiras”, como parâmetros e, portanto, conhecerá, exclusivamente, os métodos disponíveis nas interfaces injetadas. Ex.:

Vemos que, neste caso, não importa quem seja MusicPlayer, sabemos que ele possui o método Play() e que este retorna void.

Como fazemos então?

Estamos acostumados a trabalhar com referências diretas das classes que utilizamos e, neste caso, acabemos correndo o risco de modificar alguma coisa e tudo virar um caos. Portanto, utilizando a inversão de controle, a classe conhecerá apenas a interface pertinente á sua regra de negócio:

Depois disto, criamos nossa classe baseada na nossa interface e implementamos seus métodos:

Agora, sabemos que UserManager pode ser utilizado em qualquer lugar que utilize IUserManager e, neste caso, expõe à seus amigos a sua interface e permite sua utilização. Perceba que o DummyMethod não poderá ser utilizado enquanto não fizer parte de uma interface, já que ele não está assinado em IUserManager.

AnyClass pode ter acesso à todos os métodos de userManager que estejam destritos e, caso seja necessário dar manutenção em nosso código, enquanto a interface for respeitada, o funcionamento da aplicação estará intacto e estaremos felizes por mais tempo.

Concluindo

A utilização de interfaces no desacoplamento permite ao desenvolvedor codificar pensando apenas no que é pertinente à regra de negócio e garante que, enquanto as interfaces estiverem sendo respeitadas, o código de suas implementações poderá mudar e a aplicação continuará funcionando. Enfim, não devemos nos esquecer que, neste ponto, paramos de pensar nas classes  e seu código, mas devemos analisar bem as nossas interfaces.

Obs. Para a devida implantação da inversão de controle em um ambiente produtivo, podemos utilizar diversas ferramentas que criam e gerenciam os contextos da aplicação, injetando e controlando todas as interfaces e suas instâncias.

Até mais,