Come risolvere il problema delle proprietà di "naufragio del treno" che viola Law Of Demeter?

5

Ho letto della legge di Demeter e mi piacerebbe sapere come risolvere questo problema di proprietà del modello di attraversamento che vedo molto su Objective-C. So che esiste un simile domanda ma in questo caso non sto chiamando un metodo dall'ultima proprietà che fa alcuni calcoli, invece, sto solo impostando dei valori (Ok, so che i getter sono metodi ma la mia intenzione qui è solo di ottenere il valore, non cambiare lo stato di qualche oggetto).

Ad esempio:

self.priceLabel.text = self.media.ad.price.value;

Dovrei cambiarlo per qualcosa di simile:

self.priceLabel.text = [self.media adPriceValue];

e all'interno di Media.m

- (NSString *)adPriceValue {
    return [self.ad priceValue];
}

e all'interno dell'Adm

- (NSString *)priceValue {
    return [self.price value];
}

È una buona soluzione? Oppure sto creando metodi non necessari?

    
posta Raphael Oliveira 12.09.2013 - 17:04
fonte

2 risposte

4

Dopo aver letto l'articolo molto interessante pubblicato da Robert Harvey, suggerirei che se sei ancora preoccupato per il LoD fai questo (perdonami per non aver usato la sintassi ObjC qui, non ho idea di come funzioni):

/* Old code: */
void update() {
  this.priceLabel.text = this.media.ad.price.value;
}

/* New code: */
void update() {
  updateAdInfo(this.media.ad);
}
void updateAdInfo(Ad ad) {
  // Can dive a level deeper here if you want to.
  this.priceLabel.text = ad.price.value;
}

Fondamento: introducendo ulteriori getter per le proprietà secondarie, stai appiattendo il tuo modello di dominio, ed è semplicemente orribile: perdi tutta la struttura e aumenta l'accoppiamento. (Cosa succede se aggiungi una proprietà ad Ad? Ora vai in ogni singola classe che incorpora un annuncio e aggiungi getter per la nuova proprietà?)

Tuttavia, se hai una gerarchia di oggetti e una pseudo-gerarchia (parziale) di corrispondenza degli elementi di visualizzazione per visualizzarli, ha senso organizzare anche le funzioni di aggiornamento in una gerarchia.

    
risposta data 12.09.2013 - 17:30
fonte
3

Ti suggerisco di considerare quanto segue.

  1. self ha bisogno di un riferimento a media e ad , oppure self utilizza solo price ? Se utilizzi solo price , non è necessario esaminare l'intera catena.

  2. Se media.ad.price è principalmente una struttura di dati (poco o nessun comportamento / metodi), probabilmente non devi preoccuparti di Demeter.

  3. Se self usa media , ad e price , self potrebbe essere abbastanza complesso da giustificare la divisione di self in classi più piccole.

  4. Ci sono dei compromessi per nascondere o esporre i delegati. Dovresti scegliere ciò che ritieni che funzioni meglio per te ed è possibile modificare la tua implementazione in un secondo momento.

    Nascondere il delegato ti costringe a scrivere metodi di delega, ma incapsula le modifiche alla struttura. Ad esempio, se aggiungi un altro livello, ad esempio media.ad.timeSlot.price , devi solo modificare il metodo delegato, non tutte le classi che utilizzano il delegato. D'altra parte, come menzionato da Sebastian, se vuoi aggiungere una nuova proprietà o un metodo per il prezzo, devi scrivere un metodo di delega.

  5. Puoi scegliere una soluzione di medio livello. Ad esempio, potrebbe essere sensato per self ottenere un riferimento a ad , ma aggiungere un metodo a ad per restituire il valore del prezzo, in modo che self non debba navigare nel resto della struttura .

risposta data 12.09.2013 - 20:33
fonte

Leggi altre domande sui tag