Devo usare un enorme delegatore per mantenere il mio codice disaccoppiato?

5

Attualmente sto imparando ad applicare l'SRP e il codice di disaccoppiamento. Ma ho scoperto che avere un sacco di piccole classi fa esplodere i costruttori delle mie classi. E sembra un codice che usa un altro modulo della mia applicazione per conoscere più di quel modulo di quanto mi piacerebbe conoscerlo.
Ho scoperto che molti libri menzionano che le classi dovrebbero essere veramente piccole, ma non come gestire la quantità di piccole classi.

Supponiamo che abbia un modulo nella mia applicazione che riguarda il casting di contenuti su un dispositivo remoto (come il Chromecast).
Ora ho cercato di separare le mie responsabilità il più possibile.

C'è un CastErrorEventDispatcher , CastSessionHelper , CastRequestSender , CastConnectivityHelper e molti altri ancora.

Ora le altre parti della mia applicazione hanno bisogno di accedere a diversi oggetti del mio modulo di cast. Alcuni hanno bisogno solo di una classe di cui altri potrebbero aver bisogno 4. Questo sicuramente fa esplodere i costruttori.

come questo:

public class ExpandedControlsPresenter(){
    public ExpandedControlsPresenter(CastRequestSender castRequestSender,
                                     CastConnectivitySender castConnectivitySender,
                                     CastBreakEventDispatcher castBreakEventDispatcher, ...){
    ...
    }

    public void setUp(){
        castBreakEventDispatcher.addListener(...);
        castRequestSender.addListener(...);
    }
}

Questo mi riguarda perché ora il mio presentatore deve sapere tante cose sulle lezioni di casting.
Quindi mi chiedo se sarebbe meglio nascondere l'intero modulo di cast dietro a un grande delegatore.

public class CastManager {
    //Constructor with all relevant cast classes


    public void addBreakEventListener(CastBreakEventListener listener){
        castBreakEventDispatcher.addListener(listener);
    }
}

E poi basta averlo nel mio presentatore

public class ExpandedControlsPresenter(){
    public ExpandedControlsPresenter(CastManager castManager, ...){
    ...
    }

    public void setUp(){
        castManager.addBreakEventListener(...);
        castManager.addRequestSenderListener(...);
    }
}

Questo ha il vantaggio di ottenere costruttori più piccoli e posso attivare e disattivare la funzione di casting semplicemente interagendo con CastManager . Ma se ovviamente la CastManager diventerebbe incredibilmente enorme.

C'è un buon modo per affrontare questo problema?

Modifica Ho disegnato un diagramma veloce per sperare di chiarire le mie intenzioni. Voglio anche dire che so che manager non è un buon nome.

    
posta Altoyr 27.10.2016 - 22:57
fonte

2 risposte

1

Questa è in realtà una situazione in cui sei andato troppo oltre! Trovo che quando finisco con un sacco di classi di impostazioni (come i nomi CastRequestSender e CastConnectivitySender mi portano a credere che lo siano), mi piace avvolgerli in un unico grande oggetto chiamato Container per mantenermi sano di mente.

Quindi, se ti trovi con tutti questi, forse vuoi aggiungere qualcosa del genere:

public class CastSettingsContainer{
    CastRequestSender requestSender;
    CastConnectivitySender connectivitySender;
    //And so on...
}

Questo significa che ora hai un oggetto il cui unico scopo è quello di contenere un intero set di Cast Settings. Questo ti aiuta anche a disaccoppiare il codice, perché ora le altre classi non devono necessariamente conoscere le singole impostazioni di Cast, solo l'oggetto contenitore. In questo modo, puoi avere altre classi che chiedono a un CastSettingsContainer di fare cose, e lui internamente può gestire quello che sta succedendo con le diverse impostazioni. Questo dovrebbe pulire bene il tuo codice eliminando un sacco di costruttori bizzarri e spostandoli nel Container.

    
risposta data 28.10.2016 - 01:04
fonte
0

Dato questo:

castManager.addBreakEventListener(...);
castManager.addRequestSenderListener(...);

perché non registrare solo le classi dipendenti come una raccolta di ascoltatori . In questo modo, non hai serie specifiche di classi che stai iniettando nel tuo "contenitore", ma un elenco di parti interessate.

Quando si verifica un evento, puoi quindi "pubblicare" un evento e gli ascoltatori registrati possono quindi agire su quell'evento, oppure ignorarlo se lo desiderano ad es. (in pseudo-codice)

for (listener : listeners) {
   listener.startupEvent(myStartupEvent);
}

Alcuni componenti si preoccuperebbero, altri no. Potresti avere diversi insiemi / tipi di eventi e di conseguenza potresti desiderare di avere registrazioni diverse (es. Voglio registrarmi per eventi di categoria X , ma non di categoria Y , quindi potresti volere diverse raccolte di ascoltatori ...)

Trovo che questo sia un modo efficace per combinare più componenti. È flessibile (basta aggiungere un nuovo listener e / o un nuovo tipo di evento) e non si soffre l'esplosione di dipendenze e membri dei componenti. Lo svantaggio è che devi assicurarti che il tuo componente sia "cablato" correttamente, poiché perdi la tipizzazione statica che garantisce che typeA sia costruito con typeB

    
risposta data 28.10.2016 - 14:15
fonte

Leggi altre domande sui tag