Olá,
Faz algum tempo que não escrevo e o motivo disto é uma questão de tempo. Devo apresentar meu mestrado no próximo mês de Dezembro e a correria é grande para terminar tudo…
Hoje gostaria de escrever sobre um design pattern que sempre apliquei, mas que não sabia que era um design pattern. Esse tipo de situação é mais comum de acontecer do que parece… Geralmente os design patterns são soluções que as pessoas aplicam no seu dia-a-dia e que após serem consideradas viáveis e reutilizáveis são documentadas em algum catálogo de padrões.
O uso da orientação a objetos é baseado em alguns conceitos fundamentais, tais como: herança, polimorfismo, encapsulamento, estado de objetos, uso de dependências, etc.
Para que seu objeto seja um good citizen (bom cidadão) é preciso que esteja sempre em um estado consistente, isto é, todas as suas dependências (e atributos internos) devem estar em um estado adequado que permita que sua classe trabalhe corretamente. Vamos propor um exemplo: supondo que temos uma classe “Carro”, que contém um método “DarPartida()” que depende de uma instância de um “Motor” para executar a ignição. Este cenário é apresentado no código abaixo:
public class Motor { public void ExecutarIgnicao() { // Código do método... } } public class Carro { public Motor Motor { get; set; } public void DarPartida() { this.Motor.ExecutarIgnicao(); } }
Visivelmente podemos notar que se não tivermos uma instância válida de um Motor a execução do método “DarPartida” estará comprometida, podendo resultar em um defeito na nossa aplicação.
Assim, pode-se ver que o uso de construtores é essencial, pois podemos obrigar a inicialização correta de nossas dependências, como no exemplo abaixo. Assim, conseguimos garantir que nossa classe estará em um estado correto para executar todos os métodos que possuem dependências para algum atributo.
public class Carro { public Motor Motor { get; set; } public Carro(Motor motor) { this.Motor = motor; } public void DarPartida() { this.Motor.ExecutarIgnicao(); } }
Outra dica interessante é: já que vamos garantir a inicialização de nosso atributo pelo construtor então é interessante marcar a visibilidade do SET de nosso atributo como PRIVATE, pois assim evitamos que depois de inicializado, através do construtor, o atributo não será modificado por nenhum outro acesso.
public class Carro { public Motor Motor { get; private set; } public Carro(Motor motor) { this.Motor = motor; } public void DarPartida() { this.Motor.ExecutarIgnicao(); } }
Outra dica interessante é fazer uso de classes factory para criação das instâncias das dependências, assim nosso construtor irá depender exclusivamente de uma instância de uma classe factory, que irá criar todas as instâncias válidas das dependências de nossa classe “Carro”. Espero abordar com mais detalhes o uso da classe factory em outro post.
public class FactoryCarro { public Motor ConstruirMotor() { return new Motor(); } } public class Carro { public Motor Motor { get; private set; } public Carro(FactoryCarro fabrica) { this.Motor = fabrica.ConstruirMotor(); } public void DarPartida() { this.Motor.ExecutarIgnicao(); } }
Para melhorar este exemplo é interessante fazer o uso de interfaces, para diminuirmos as dependências à classes concretas em nosso código. Veja como isso ficaria logo abaixo:
public interface IMotor { void ExecutarIgnicao(); } public class Motor : IMotor { public void ExecutarIgnicao() { // Código do método... } } public interface IFabricaCarro { IMotor ConstruirMotor(); } public class FactoryCarro : IFabricaCarro { public IMotor ConstruirMotor() { return new Motor(); } } public interface ICarro { IMotor Motor { get; } void DarPartida(); } public class Carro { public IMotor Motor { get; private set; } public Carro(FactoryCarro fabrica) { this.Motor = fabrica.ConstruirMotor(); } public void DarPartida() { this.Motor.ExecutarIgnicao(); } }
Espero que este exemplo seja proveitoso a todos.
Obrigado e até o próximo.
[]s!
Por
Fernando Henrique Inocêncio Borba Ferreira
Microsoft Most Valuable Professional – Data Plaftorm Development
Para tal contexto, não vejo utilidade em forneceer uma fábrica no construtor (salvo sobre seu problema abordar a construção de carros com diferente fábrica de motores – coisa muito dificil acontecer no mundo real [ ex: gol com motor vhc do celta ] ).
Olá Wellington,
Tudo beleza? Sim, realmente por ser um exemplo bastante simples não existe a necessidade da factory. Mas, quando o criei esta pensando em algo que possibilitasse a criação de motores 1.0, 1.4, 2.0 e assim por diante. Espero em um próximo post abordar melhor este pattern.
Obrigado por escrever.
[]s!