2010-05-28 15 views
5

Considerare la seguente analogia: Se abbiamo una classe: "Car" ci si potrebbe aspettare che abbia un'istanza di "Engine" in essa. Come in: "La macchina HAS-A motore". Allo stesso modo, nella classe "Engine" ci aspetteremmo un'istanza di "Starting System" o "Cooling System" che hanno le loro sub-componenti appropriate.Qual è la regola generale sull'esporre metodi di classe incapsulati

Per la natura dell'incapsulamento, non è vero che l'auto "HAS-A" "tubo del radiatore" in esso così come il motore?

Pertanto, è opportuno OO a fare qualcosa di simile:

public class Car { 
    private Engine _engine; 

    public Engine getEngine() { 
     return _engine; 
    } 

    // is it ok to use 'convenience' methods of inner classes? 
    // are the following 2 methods "wrong" from an OO point of view? 
    public RadiatorHose getRadiatorHose() { 
     return getCoolingSystem().getRadiatorHose(); 
    } 

    public CoolingSystem getCoolingSystem() { 
     return _engine.getCoolingSystem(); 
    } 
} 

public class Engine { 
    private CoolingSystem _coolingSystem; 

    public CoolingSystem getCoolingSystem() { 
     return _coolingSystem; 
    } 
} 

public class CoolingSystem { 
    private RadiatorHose _radiatorHose; 

    public RadiatorHose getRadiatorHose() { 
     return _radiatorHose; 
    } 
} 

public class RadiatorHose {//... 
} 

risposta

2

Con il raggiungimento all'interno di altre classi incapsulate siete in cerca di guai. L'intero punto di incapsulamento è che non è necessario conoscere come viene implementata la funzione, piuttosto cosa fa e come accedervi.
Se dovessi modificare un modo in cui il sistema di raffreddamento e il tubo del radiatore interagissero, il motore non dovrebbe subire alcun effetto. Nel caso in cui tu metti avanti, questo potrebbe causare problemi. Questo non è corretto OOP e causerà problemi in futuro.

0

Come regola generale, è possibile utilizzare prima il linguaggio della natura per descrivere le relazioni tra i componenti, che sono recentemente rappresentate come classi e quindi utilizzare determinati diagrammi per presentare queste relazioni. Se due componenti sono collegati nei diagrammi, dovrebbero avere una certa connessione nel programma. Nel tuo caso, puoi determinare se "engine" è un'istanza di "car" e "cooling system" è un'istanza di "engine" osservando se ci sono connessioni tra questi componenti nel tuo diagramma. (Questo processo è in realtà l'intuizione del linguaggio di modellazione OO come UML.)

In effetti, non vedo nulla di sbagliato nel codice. Non sono un automobilista, quindi potrei avere torto nel capire il sistema. Ma se il motore di un'automobile reale ha bisogno di un sistema di raffreddamento, penso che quello che stai facendo sia corretto. Sì, la classe "motore" chiama la proprietà della classe "sistema di raffreddamento", ma poiché il "motore" utilizza il metodo pubblico per invocare il "sistema di raffreddamento", è la strada giusta. Ancora una volta, non conosco il vero sistema automobilistico, quindi potrei sbagliarmi su questo particolare progetto.

4

Ecco davvero un buon (e abbastanza breve) di carta sulla legge di Demetra chiamato The Paperboy, il portafoglio, e la legge di Demetra:

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

volta, avete letto dovresti leggere questo breve articolo che spiega in dettaglio quante persone interpretano male la legge di Demeter. In questo modo, l'articolo si comporta come una spiegazione davvero buona. È giustamente chiamato "La legge di Demetra non è un esercizio di conteggio dei punti" !!!!

http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx

+0

Ho appena finito il PDF e era quasi attraverso con l'articolo già - ma questo potrebbe essere utile a qualcun altro. +1 – javamonkey79

Problemi correlati