La base di codice su cui sto lavorando spesso utilizza variabili di istanza per condividere dati tra vari metodi banali. Lo sviluppatore originale è fermamente convinto che ciò aderisca alle migliori pratiche dichiarate nel libro di Clean Code di zio Bob / Robert Martin: "La prima regola delle funzioni è che dovrebbero essere piccole". e "Il numero ideale di argomenti per una funzione è zero (niladic). (...) Gli argomenti sono difficili. Prendono molto potere concettuale."
Un esempio:
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);
}
}
Rifletterei questo nel seguente usando variabili locali:
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);
}
}
Questo è più breve, elimina l'accoppiamento di dati implicito tra i vari metodi banali e limita gli ambiti variabili al minimo richiesto. Eppure, nonostante questi vantaggi, non riesco ancora a convincere lo sviluppatore originale che questo refactoring è giustificato, poiché sembra contraddire le pratiche di zio Bob di cui sopra.
Da qui le mie domande: qual è l'obiettivo logico scientifico per favorire le variabili locali rispetto alle variabili di istanza? Non riesco proprio a metterci il dito sopra. La mia intuizione mi dice che gli accoppiamenti nascosti sono cattivi e che uno scopo ristretto è meglio di uno ampio. Ma qual è la scienza per sostenere questo?
E viceversa, ci sono degli svantaggi di questo refactoring che forse ho trascurato?