Design accettabile per utilizzare oggetti membri pubblici nella composizione?

3

Dire che ho una grande classe chiamata Root , che ha molti membri e amp; funzioni:

class Root {
public:
    void func1(); // operates on a and b
    void func2(); 
    ...       
private:
    A a;
    B b;
    C c;
    ...
};

La classe Root sta diventando un po 'grande quindi decido di scomporre alcune delle variabili membro e una funzione in un'altra classe:

class AB {
public:
    void func1();
    ...
private:
    A a;
    B b;
};

Quindi, usando la composizione, posso rendere AB ab una variabile membro di Root . Root ora è un po 'più piccolo / più pulito / più gestibile. La domanda riguarda il livello di accesso di ab dopo questo refactoring.

Va bene in questo caso che ab sia un membro pubblico? Qualsiasi aspetto negativo? I membri pubblici sono generalmente considerati di cattivo design da ciò che ho letto. Ma qui l'incapsulamento / esposizione globale non è realmente cambiato ... gli oggetti a e b sono privati in AB quindi sono ancora nascosti dall'esterno.

(Sidenote: il motivo per cui vorrei rendere pubblico ab è che consente un più facile attraversamento della gerarchia di composizione di Root . Ad esempio in Root membro c Potrei voler chiamare func1 :

void C::foo(Root& root) {
    //do some stuff
    root.ab.func1();
}

Se ab era privato, dovrei definire una funzione pass-through in root .)

    
posta badger5000 13.12.2015 - 20:42
fonte

2 risposte

2

Se la classe C vuole chiamare func1() quindi passare l'oggetto ab alla funzione foo di C invece di passare l'oggetto root . Questo descrive meglio cosa sta succedendo agli altri programmatori e in futuro a te. Ti dice che C non ha bisogno che tutta Root faccia il suo lavoro, ha solo bisogno di AB (e potrebbe teoricamente ottenere un AB da una sorgente diversa da Root).

void C::foo(AB& ab) {
    //do some stuff
    ab.func1();
}

Se fossi in te, vorrei anche passare e cambiare qualsiasi altra classe che sta accedendo a Root per chiamare semplicemente func1() di AB (e qualsiasi altra funzione tu possa spostare nella classe AB.

Fai questo con l'occhio di distruggere Root anche in altri modi. Se è molto grande come dici tu, allora ci sono molte piccole classi che cercano di uscire ...

    
risposta data 14.12.2015 - 00:54
fonte
2

Sia dal punto di vista accademico che tecnico, è non ok.

Da un punto di vista accademico, stai violando il principio dell'incapsulazione.

Da un punto di vista tecnico, se hai bisogno di fare ulteriori refactoring in futuro, avrai molto lavoro da fare.

Detto questo, c'è anche un punto di vista pratico, che si riduce a questo: se il tuo IDE ti dà la possibilità di refactoring ab da pubblico a privato, aggiungendo tutti gli accessor necessari e sostituendo tutti i riferimenti a root.ab con invocazioni di questi accessor su tutto il tuo codice base, e se può farlo con solo un paio di clic e sequenze di tasti, stai bene. In caso contrario, è meglio non farlo.

Non mi è chiaro cosa intendi per sotto-oggetto c , ma se intendi una sottoclasse, considera di fare ab protected . In questo modo, c sarà in grado di accedervi, ma nessun codice esterno lo farà.

    
risposta data 13.12.2015 - 20:59
fonte

Leggi altre domande sui tag