La "Legge di Demetra" è applicabile alle firme del metodo pubblico / API?


10

Dato che le modifiche alla firma dell'API / del metodo pubblico dovrebbero essere minime per evitare la violazione di quei codici client che utilizzano questi metodi, mi chiedevo se la Legge di Demetra fosse meno applicabile a questi.

Un semplice esempio:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

Si noti che il metodo di addebito passa l'oggetto Transaction piuttosto che solo un doppio importo (la "Legge di Demeter", a quanto ho capito, direbbe semplicemente di passare le informazioni richieste, in questo caso solo l'importo, non l'oggetto Transaction ... ). Il motivo dietro questo, è perché il metodo in futuro potrebbe richiedere alcune altre proprietà Transazione oltre all'importo. Da quanto ho capito, questo impedirà di rompere la firma del metodo aggiungendo un nuovo parametro in futuro.

Questo lo rende quindi una scelta sensata? Oppure mi sfugge qualcosa?

Risposte:


3

Ma questo non infrange la Legge di Demetra.

Più formalmente, la Legge di Demetra per le funzioni richiede che un metodo M di un oggetto O possa invocare solo i metodi dei seguenti tipi di oggetti:

  • O stesso
  • Parametri di M.
  • qualsiasi oggetto creato / istanziato all'interno di M
  • Oggetti componenti diretti di O.
  • una variabile globale, accessibile da O, nell'ambito di M

Wikipedia: Legge di Demetra

La transazione è un argomento per il metodo di addebito, quindi chiamare t.getAmount () va bene.

Modifica: frainteso ciò, stai dicendo che il LoD vorrebbe passare l'importo della transazione, non un oggetto Transaction. In tal caso, sì, penso che questo sia un buon posto per romperlo, sapendo che in futuro avrai bisogno di più dall'oggetto Transaction. Inoltre, l'incapsulamento delle primitive negli oggetti a livello di dominio è un'altra buona pratica di programmazione.

Modifica 2: dopo aver letto che potrebbe aver bisogno di più in futuro, si potrebbe anche vedere questo come placcatura in oro non necessaria. Fornire un metodo che ora richiede un doppio (o meglio una classe Money) è sufficiente. Se in seguito è necessario un argomento Transaction non è disastroso fornire una seconda firma che accetta una Transaction, ma continuare a supportare la firma originale. Non è che implementeresti due metodi, uno chiamerebbe l'altro.


Grazie per il tuo contributo. Sono d'accordo sulle primitive incapsulanti negli oggetti di dominio. Tuttavia, solo il punto in Modifica 2, dici che non è disastroso aggiungere una nuova seconda firma, ma ciò significherebbe cambiare il codice nel codice client che ora dovrebbe passare 2 parametri invece di uno. Quel secondo punto, sono un po 'titubante nel concordare ...
Carlos Jaime C. De Leon il

Modifica 2 è soggettivo, sono d'accordo.
Sean,

0

Se hai intenzione di espandere la Accountclasse in futuro, direi che questa è una situazione in cui rendere l' Transactionoggetto più generico sarebbe una buona flessione delle regole della Legge.

Per esempio:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

Penso di essere un po 'deviato dalla domanda originale, ma il mio punto è che mentre potresti essere preoccupato di allontanarti dalla Legge di Demetra, i vantaggi di farlo superano gli aspetti negativi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.