Navigando attraverso un codice che ho scritto, ho trovato il seguente costrutto che mi ha fatto riflettere. A prima vista, sembra abbastanza pulito. Sì, nel codice effettivo il metodo getLocation()
ha un nome leggermente più specifico che descrive meglio esattamente quale posizione ottiene.
service.setLocation(this.configuration.getLocation().toString());
In questo caso, service
è una variabile di istanza di un tipo noto, dichiarata all'interno del metodo. this.configuration
deriva dall'essere passato al costruttore della classe ed è un'istanza di una classe che implementa un'interfaccia specifica (che impone un metodo pubblico getLocation()
). Quindi, il tipo di ritorno dell'espressione this.configuration.getLocation()
è noto; specificamente in questo caso, è un java.net.URL
, mentre service.setLocation()
vuole String
. Poiché i due tipi String e URL non sono direttamente compatibili, è necessaria una sorta di conversione alcuni per adattare il picchetto quadrato al foro rotondo.
Tuttavia , secondo la legge di Demeter come citato in Clean Code , un metodo f nella classe C dovrebbe chiamare solo metodi su C , oggetti creati o passati come argomenti a f e oggetti tenuti in variabili di istanza di C . Qualunque cosa al di là di questo (l'ultimo toString()
nel mio caso particolare sopra, a meno che tu non consideri un oggetto temporaneo creato come risultato dell'invocazione del metodo stesso, nel qual caso l'intera Legge sembra essere discutibile) non è consentito.
Esiste un ragionamento valido per cui una chiamata come sopra, dati i vincoli elencati, dovrebbe essere scoraggiata o addirittura non consentita? O sono semplicemente troppo pignolo?
Se dovessi implementare un metodo URLToString()
che chiama semplicemente toString()
su un oggetto URL
(come quello restituito da getLocation()
) passato ad esso come parametro, e restituisce il risultato, potrei avvolgere il getLocation()
chiama per ottenere esattamente lo stesso risultato; efficacemente, vorrei solo spostare la conversione di un passo verso l'esterno. Questo in qualche modo lo renderebbe accettabile? (Mi sembra per me, intuitivamente, che non dovrebbe fare alcuna differenza in entrambi i modi, dal momento che tutto ciò che fa è spostare le cose un po '. Tuttavia, seguendo la lettera della Legge di Demetra come citato, sarebbe accettabile, dal momento che poi opererei direttamente su un parametro per una funzione.)
Farebbe qualche differenza se si trattasse di qualcosa di leggermente più esotico di chiamare toString()
su un tipo standard?
Quando rispondi, tieni presente che alterare il comportamento o l'API del tipo di cui fa la variabile service
non è pratico. Inoltre, per amor di discussione, diciamo che anche alterare il tipo di ritorno di getLocation()
è impraticabile.