Prefira composição ao invés de herança, um simples exemplo em Ruby
Criado em: 15/02/2013
Um dos princípios da orientação a objetos é:
Prefira composição de objetos à herança de classes
como é descrito no livro Design Patterns: Elements of Reusable Object-Oriented Software da GoF. Vamos agora ver um exemplo prático em ruby de como podemos usar composição ao invés de herança.
O problema
Nossas classes representam um carro e os componentes que podem ser adicionados ao carro, os componentes são alarme e ar-condicionado, e o que precisamos saber ao final é o preço do carro.
Usando herança
Seguindo uma implementação baseada em herança teríamos algo assim:
Nossas classes são bem simples e usadas assim:
Os 2 primeiros casos (CarWithAlarm
e CarWithAirConditioning
) funcionam muito bem, já o terceiro caso CarWithAlarmAndAirConditioning
temos os seguintes problemas:
- repetição - pois pegamos o valor adicionado de
CarWithAlarm
eCarWithAirConditioning
e somamos para chegar ao preço deCarWithAlarmAndAirConditioning
- dificil de manter - pois se o valor de
CarWithAlarm
mudar teremos que lembrar de alterar emCarWithAlarmAndAirConditioning
- dificil de estender - imagine se tivermos mais um componente, Radio, teremos que criar:
CarWithRadio
CarWithRadioAndAlarm
CarWithRadioAndAirConditioning
CarWithRadioAlarmAndAirConditioning
deu para perceber que estamos fazendo errado né? Vamos agora ao exemplo usando composição.
Usando composição
Primeiro criamos a nossa classe Car
:
Vamos analisar a nossa classe.
Initialize
Criamos 2 váriaveis de instância:
@price
que é o preço do nosso carro@components
um array para armazenar os componentes de nosso carro
add_component
Método que adiciona um componente ao nosso carro.
price
Retorna o preço total do carro
Tendo nossa classe Car
criada vamos as classes de componentes:
Agora com nossas classes de componentes criadas, vamos a um exemplo de como podemos usar a nossa classe Car
, agora utilizando de composição.
Como pode ver obtivemos o mesmo resultado que tinhamos com a classe CarWithAlarm
, agora se precisarmos ter o mesmo resultado de CarWithAlarmAndAirConditioning
fariamos:
como podemos ver com composição obtivemos um código bem mais fácil de se manter, estender e sem repetições.
Usámos o carro e seus componentes, mas poderia ser a modelagem de uma transação bancária que possui diversas taxas diferentes por exemplo.
Comentários
Comentários powered by Disqus