Separazione di preoccupazione / principio di responsabilità singola

7

Ho appena letto i principi SOLID, e questo è uno di quelli con cui ho davvero difficoltà durante la progettazione del software. Sono relativamente nuovo (4 mesi professionalmente) nella codifica.

L'idea è semplicemente di incapsulare le classi in quelle che eseguono un singolo compito.

Ad esempio, cosa succede se hai una classe che crea e popola una Treeview e la configura secondo le tue specifiche. Quindi si desidera che i dati recuperati da un database quando l'utente fa clic sui nodi. Diresti che si tratta di due preoccupazioni separate?

  1. Compila e configura la visualizzazione ad albero
  2. Ottieni dati dal database?

Inoltre, nella stessa app. Hai una vista datagrid che viene anche popolata con dati dinamici. Metteresti quindi il recupero dei dati nella stessa classe del recupero dei dati di treeview o sarebbe ancora un'altra classe completamente separata?

Grazie.

    
posta Darren Young 21.01.2011 - 09:34
fonte

5 risposte

7

Separazione dei dubbi

Ogni oggetto fa il proprio lavoro. Quindi nel tuo esempio la vista ad albero sa solo di essere una vista ad albero (presumibilmente visualizzando i dati). Potrebbe caricare i propri dati ma non dovrebbe sapere da dove provengono i dati. Se sa che i dati provengono da allora, è strettamente associato alla fonte dei dati (ad esempio, potrebbe essere un DB ora, ma cosa succede nella versione 2 quando è necessario ottenere i dati dallo space shuttle?).

Invece dovresti passare alla vista ad albero un'interfaccia (che sa come usarla) per recuperare i suoi dati da:

// Example
class DataRetrieveInterface
{
     // STUFF
     virtual std::string getItemAt(int index)  = 0;
};
class DBDataRetriever:      public DataRetrieveInterface {};
class ShuttleDataRetriever: public DataRetrieveInterface {};
class MockDataRetriever:    public DataRetrieveInterface { /* Needed for testing */ }

class TreeView
{
    public:
        TreeView(DataRetrieveInterface& data)
        {
             // use data to populate the view.
        }
};

Se riutilizzi DataRetrieveInterface per la griglia è qualcosa che devi decidere come parte del tuo progetto. È abbastanza generico? In alternativa puoi derivare da questa interfaccia e avere qualcosa di più specifico della griglia per l'oggetto della griglia. A questo punto non ci sono abbastanza informazioni nella domanda da dire se dovresti o non dovresti avere un'interfaccia diversa per la griglia.

    
risposta data 21.01.2011 - 09:54
fonte
3

Separa la serializzazione / deserializzazione dalle classi

Ho scoperto personalmente che è preferibile separare la serializzazione / deserializzazione dalle classi reali. Se hai una classe che fornisce dati in qualche formato (xml / dataset / json o cosa preferisci) crea / carica la classe. La classe non dovrebbe avere dipendenze relative alla serializzazione.

In questo modo puoi più facilmente cambiare i metodi di serializzazione, supportare diversi tipi di dati e così via

    
risposta data 21.01.2011 - 10:05
fonte
1

Il rendering dei dati e il recupero dei dati sono due problemi distinti e quindi appartengono a oggetti separati.

Potresti avere una situazione in cui ha senso avere una singola classe di recupero dei dati che fornisce i dati a una vista ad albero ea una griglia di dati: due diverse viste sugli stessi dati. Fuori mano sembra improbabile: alberi e tavoli non sono molto simili.

    
risposta data 21.01.2011 - 09:48
fonte
0

Pensa a come scrivere un test unitario per quella classe.

Quale funzionalità separata può e vorresti testare? La compilazione di dati, la configurazione, il caricamento dal database sono preoccupazioni separate. La loro suddivisione li rende più facili da capire, testare e riutilizzare.

    
risposta data 21.01.2011 - 10:01
fonte
0

Forse troverai più facile pensarlo meno come una teoria e più come una cosa pratica.

Immagina di scrivere due app che forniranno funzionalità identiche ma attraverso due front-end completamente diversi: un client Web, un client desktop nativo (supponi che entrambi siano scritti nella stessa lingua).

Ora, progetta e codifica in modo tale da avere il minimo di duplicazione che sia praticamente possibile.

In termini di separazione del recupero dei dati (ottenendo effettivamente i dati) e della logica aziendale (applicando l'elaborazione e la logica a tali dati), fare lo stesso, ma ora supponendo che sarà necessario implementare la stessa soluzione sia per SQL Server che per i dati archiviazione utilizzando file flat XML.

Ancora una volta, progettazione e codice in modo tale da avere la duplicazione il più possibile praticamente possibile.

    
risposta data 21.01.2011 - 11:14
fonte

Leggi altre domande sui tag