La base de código en la que estoy trabajando con frecuencia usa variables de instancia para compartir datos entre varios métodos triviales. El desarrollador original insiste en que esto se adhiere a las mejores prácticas establecidas en el libro Clean Code del tío Bob / Robert Martin: "La primera regla de funciones es que deberían ser pequeñas". y "El número ideal de argumentos para una función es cero (niládico). (...) Los argumentos son difíciles. Toman mucho poder conceptual".
Un ejemplo:
public class SomeBusinessProcess {
@Inject private Router router;
@Inject private ServiceClient serviceClient;
@Inject private CryptoService cryptoService;
private byte[] encodedData;
private EncryptionInfo encryptionInfo;
private EncryptedObject payloadOfResponse;
private URI destinationURI;
public EncryptedResponse process(EncryptedRequest encryptedRequest) {
checkNotNull(encryptedRequest);
getEncodedData(encryptedRequest);
getEncryptionInfo();
getDestinationURI();
passRequestToServiceClient();
return cryptoService.encryptResponse(payloadOfResponse);
}
private void getEncodedData(EncryptedRequest encryptedRequest) {
encodedData = cryptoService.decryptRequest(encryptedRequest, byte[].class);
}
private void getEncryptionInfo() {
encryptionInfo = cryptoService.getEncryptionInfoForDefaultClient();
}
private void getDestinationURI() {
destinationURI = router.getDestination().getUri();
}
private void passRequestToServiceClient() {
payloadOfResponse = serviceClient.handle(destinationURI, encodedData, encryptionInfo);
}
}
Refactorizaría eso en lo siguiente usando variables locales:
public class SomeBusinessProcess {
@Inject private Router router;
@Inject private ServiceClient serviceClient;
@Inject private CryptoService cryptoService;
public EncryptedResponse process(EncryptedRequest encryptedRequest) {
checkNotNull(encryptedRequest);
byte[] encodedData = cryptoService.decryptRequest(encryptedRequest, byte[].class);
EncryptionInfo encryptionInfo = cryptoService.getEncryptionInfoForDefaultClient();
URI destinationURI = router.getDestination().getUri();
EncryptedObject payloadOfResponse = serviceClient.handle(destinationURI, encodedData,
encryptionInfo);
return cryptoService.encryptResponse(payloadOfResponse);
}
}
Esto es más corto, elimina el acoplamiento de datos implícito entre los diversos métodos triviales y limita los alcances variables al mínimo requerido. Sin embargo, a pesar de estos beneficios, todavía no puedo convencer al desarrollador original de que esta refactorización está justificada, ya que parece contradecir las prácticas del tío Bob mencionadas anteriormente.
De ahí mis preguntas: ¿Cuál es la razón objetiva y científica para favorecer las variables locales sobre las variables de instancia? Parece que no puedo señalarlo. Mi intuición me dice que los acoplamientos ocultos son malos y que un alcance estrecho es mejor que uno amplio. Pero, ¿cuál es la ciencia para respaldar esto?
Y a la inversa, ¿hay alguna desventaja en esta refactorización que posiblemente haya pasado por alto?