Die Codebasis, an der ich arbeite, verwendet häufig Instanzvariablen, um Daten zwischen verschiedenen einfachen Methoden auszutauschen. Der ursprüngliche Entwickler ist der festen Überzeugung, dass dies den Best Practices entspricht, die im Clean Code- Buch von Onkel Bob / Robert Martin aufgeführt sind: "Die erste Regel für Funktionen lautet, dass sie klein sein sollten." und "Die ideale Anzahl von Argumenten für eine Funktion ist null (niladisch). (...) Argumente sind schwer. Sie erfordern viel konzeptionelle Kraft."
Ein Beispiel:
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);
}
}
Ich würde das in das Folgende umgestalten, indem ich lokale Variablen verwende:
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);
}
}
Dies ist kürzer, eliminiert die implizite Datenkopplung zwischen den verschiedenen trivialen Methoden und beschränkt die Gültigkeitsbereiche der Variablen auf das erforderliche Minimum. Trotz dieser Vorteile kann ich den ursprünglichen Entwickler immer noch nicht davon überzeugen, dass dieses Refactoring gerechtfertigt ist, da es den oben erwähnten Praktiken von Onkel Bob zu widersprechen scheint.
Daher meine Fragen: Was ist das objektive wissenschaftliche Argument, um lokale Variablen vor Instanzvariablen zu bevorzugen? Ich kann es nicht genau sagen. Meine Intuition sagt mir, dass versteckte Kopplungen schlecht sind und dass ein enger Bereich besser ist als ein breiter. Aber was ist die Wissenschaft, um dies zu unterstützen?
Und umgekehrt, gibt es Nachteile bei diesem Refactoring, die ich möglicherweise übersehen habe?