Bom, se você tem uma classe, e usa uma composição, deve se ater a deixar a classe com baixo acoplamento, a sua classe deve conhecer o minímo a respeito da outra
classe, isso é conseguido usando uma interface bem definida, entende-se por interface os métodos que está presentes na API.
Vamos pensar, se você altera o construtor de uma classe, e todas as classes que a usam(exemplo do motor) devem passar a construir um motor com argumentos esses
argumentos será necessários vir de algum lugar certo? Sendo assim penso que a mulher coisa no entanto é começar a discussão levando em consideração que estamos
em um fórum de java básico, e realmente, pelo menos eu, ainda não sou perito em arquitetura, design Patterns e outras nuances que envolvem os problemas estruturais de projeto, mas de qualquer forma devemos nos ater a uma coisa chamada IOC, podemos então partir do princípio que estamos falando de um problema de acoplamento certo? podemos começar pensando se a injeção de dependência ou a inversão de controle podem ou não resolver (amenizar) o nosso problema…Li um pouco de Spring, e esse framework provê formas de "injeção", sendo por setter ou por Construtor, o que acha de mudar sua classe Motor para Interface Motor?
------->IOC e Injeção de Dependência tem muitas discussões a respeito não estamos tratando do que é e como é!!!
para saber mais sobre o assunto
public interface Motor {
}
public class Carro {
private String nome;
private int velocidadeMaxima;
private Motor motor;
Carro(String nome,int velocidadeMaxima, Motor motor){
this.nome = nome;
this.velocidadeMaxima = velocidadeMaxima;
this.motor = motor;
}
}
public class MotorFerrari implements Motor {
String tipo;
MotorFerrari(String tipo){
this.tipo = tipo;
}
}
Com Spring poderiamos fazer uma injeção em Carro, desta forma de uma classe que implementa Motor, veja abaixo nos xmls que você injeta as propriedades no
construtor… pode haver erros no xml por que eu não estou testando aqui, o mais importante e a idéia…
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="carro" class="Carro">
<constructor-arg index="0" ref="motor"/>
</bean>
<bean id="motor" class="MotorFerrari" scope="prototype">
<constructor-arg value="ferrari"/>
</bean>
</beans>
Ae depois seria somente carregar o xml na aplicação…
veja que agora o controle de “instanciar” um motor não é mais responsabilidade de “Carro” e sim do framework, sendo assim se você mudar o construtor, vai mudar
ali, somente no xml, e se precisar de outras implemtações vai fazer… os nomes ali talves não estejam muito bons… mas na verdade a idéia e apenas introduzir uma visão de escopo de solução…
Vejamos outra solução possível:
poderia apenas alterar a classe interna e chamar o constutor dentro de motor… e desta forma obter os valores do construtor de metodos estaticos…
desta forma suas classes não seriam os provedores dos atributos para o construtor e sim métodos utilitários, veja que a mudança é inevitável, temos
que garantir boas unidades de testes, acredito que Junit aliado a uma implementação com testes para todos os métods deixaria a mudança menos “traumática” sendo que uma vez mudando o sistema teriamos a possibilidade de rodar os testes, e encontrariamos os possíveis pontos de erro! podendo de forma mais rápida
“concertar os estragos”…bom abaixo uma possível implentação do “amenizador”
public class Motor {
String tipo;
Motor() {
this(retonaTipo(), new String[] { "arg1", "arg2" });
}
Motor(String tipo, String... args) {
this.tipo = tipo;
}
static String retonaTipo() {
return "tipoPegoDeAlgumLugarDoMundo";
}
}
}
Espero ter ajudadeo, e comentem o caso!