Qual è la differenza tra il principio di responsabilità singola e la separazione delle preoccupazioni

17

a) Qual è la differenza tra SRP e SoC ? Forse SRP è applicato a livello di classe, mentre SoC può essere applicato a sistema , sottosistema , modulo , classe o funzione livelli.

b) Se la risposta a a) è sì, allora SoC applicato a livello di classe un sinonimo di SRP ?

grazie

    
posta user1483278 04.07.2012 - 20:56
fonte

4 risposte

13

Il principio di responsabilità unica riguarda il fatto che il tuo codice fa solo 1 cosa e puoi suddividere tutte le funzionalità in diverse classi che sono tutte pensate per fare una cosa specifica. Un esempio è una classe specifica per la convalida, l'esecuzione di alcune logiche di business, l'arricchimento di un modello, il recupero di dati, l'aggiornamento di dati, la navigazione, ecc.

The Separation of Concerns riguarda il fatto che il tuo codice non è strettamente associato ad altre classi / sistemi. L'utilizzo di interfacce nel codice aiuta molto, in questo modo è possibile associare liberamente classi / sistemi al codice. Un punto cruciale su questo è che è più facile testare il tuo codice anche in unità. Esistono molti framework (IoC) che possono aiutarti a raggiungere questo obiettivo, ma puoi implementare anche tu una cosa del genere.

Un esempio di qualcosa SoC, ma senza SRP

public class Foo
{
    private readonly IValidator _validator;
    private readonly IDataRetriever _dataRetriever;

    public Foo(IValidator validator, IDataRetriever dataRetriever)
    {
        _validator = validator;
        _dataRetriever = dataRetriever;
    }

    public NavigationObject GetDataAndNavigateSomewhereIfValid()
    {
        var data = _dataRetriever.GetAllData();

        if(_validator.IsAllDataValid(data))
        {
            object b = null;
            foreach (var item in data.Items)
            {
                b = DoSomeFancyCalculations(item);
            }

            if(_validator.IsBusinessDataValid(b))
            {
                return ValidBusinessLogic();
            }
        }
        return InvalidItems();
    }

    private object DoSomeFancyCalculations(object item)
    {
        return new object();
    }
    private NavigationObject ValidBusinessLogic()
    {
        return new NavigationObject();
    }

    private NavigationObject InvalidItems()
    {
        return new NavigationObject();
    }
}

Come puoi vedere, questo codice non è strettamente accoppiato a classi o altri sistemi, perché usa solo alcune interfacce per fare cose. Questo è positivo dal punto di vista del SoC.

Come puoi vedere questa classe contiene anche 3 metodi privati che fanno cose fantasiose. Da un punto di vista SRP, questi metodi dovrebbero probabilmente essere collocati all'interno di alcune classi. 2 di loro fanno qualcosa con la navigazione, che si adatterebbe in qualche classe di INavigation. L'altro fa alcuni calcoli elaborati su un oggetto, questo potrebbe probabilmente essere collocato all'interno di una classe IBusinessLogic.

Avendo qualcosa del genere, entrambi hanno SoC e SRP al loro posto:

public class Foo
{
    private readonly IValidator _validator;
    private readonly IDataRetriever _dataRetriever;
    private readonly IBusinessLogic _businessLogic;
    private readonly INavigation _navigation;

    public Foo(IValidator validator, IDataRetriever dataRetriever, IBusinessLogic businessLogic, INavigation navigation)
    {
        _validator = validator;
        _dataRetriever = dataRetriever;
        _businessLogic = businessLogic;
        _navigation = navigation;
    }

    public NavigationObject GetDataAndNavigateSomewhereIfValid()
    {
        var data = _dataRetriever.GetAllData();

        if(_validator.IsAllDataValid(data))
        {
            object b = null;
            foreach (var item in data.Items)
            {
                b = _businessLogic.DoSomeFancyCalculations(item);
            }

            if(_validator.IsBusinessDataValid(b))
            {
                return _navigation.ValidBusinessLogic();
            }
        }
        return _navigation.InvalidItems();
    }
}

Naturalmente potresti discutere se tutta questa logica dovrebbe essere inserita nel metodo GetDataAndNavigateSomewhereIfValid . Questo è qualcosa che dovresti decidere per te stesso. A me sembra che questo metodo stia facendo troppe cose.

    
risposta data 04.07.2012 - 21:37
fonte
2

Come per SRP che viene applicato solo a livello di classe, nei suoi libri Robert C. Martin (per quanto ne so ha reso popolare se non è venuto fuori con il concetto) afferma:

Pulisci codice, pagina. 138 : "Il Single Responsibility Principle (SRP) afferma che una classe o modulo dovrebbe avere una, e solo una, ragione per cambiare."

In Agile Principles, Pattern and Practices in C #, pagina 116 : "[...] e mette in relazione la coesione con le forze che causano un modulo , o una classe , per cambiare. "

Enfasi su enfasi.

In APPP parla in modo più approfondito di SRP e si concentra quasi interamente a livello di classe. Mentre sembra focalizzarsi sul livello di classe, ritengo che il principio sia rivolto anche a moduli e altri costrutti di livello superiore.

Per questo motivo non classificherei SRP come SoC a livello di classe come suggerisci nella tua domanda.

    
risposta data 04.07.2012 - 21:29
fonte
0

Qui puoi trovare un breve video che spiega chiaramente la differenza tra queste terminologie. link

Separazione delle preoccupazioni (SoC). Dividi la tua applicazione in funzioni distinte con il minimo sovrapposizione di funzionalità possibile. (Microsoft).

"Concern"="feature distinta"="sezione distinta"

"Concern" funziona sia a livello alto che a basso

Principio di responsabilità singola afferma che ogni modulo o classe dovrebbe avere responsabilità su una singola parte della funzionalità fornita dal software e che tale responsabilità dovrebbe essere interamente incapsulata dalla classe. Tutti i suoi servizi dovrebbero essere strettamente allineati a tale responsabilità. (Definizione di Wikipedia)

"Responsabilità"="motivo per cambiare"

cambia cosa? "Una singola parte della funzionalità fornita dal software" = Unità di base

Conclusione

Il principio di responsabilità singola funziona su unità di base - > funziona a basso livello

Separation of Concerns funziona sia a livello alto che basso

SRP e SoC lavorano insieme per la separazione delle preoccupazioni. Sono esattamente uguali a basso livello

    
risposta data 31.01.2016 - 19:06
fonte
0

Ecco la mia comprensione di questi principi.

Separation of Concerns (SoC) - riguarda la divisione di un sistema software in moduli più piccoli, ciascuno su questi moduli è responsabile di un singolo problema. Una preoccupazione, in questo caso, è una funzionalità o un caso d'uso di un sistema software. Un modulo ha un'API (interfaccia) ben definita come risultato che rende un intero sistema altamente coeso. Esistono due tipi principali: orizzontale e verticale.

Principio di Responsabilità Unica (SRP) - è un principio di progettazione che afferma che ogni blocco predefinito (può essere una classe, un modulo, un oggetto o anche una funzione) di un sistema dovrebbe avere solo una singola responsabilità. Robert C. Martin. Martin descrive una responsabilità come una ragione per cambiare. In generale, è molto meglio avere una singola classe / oggetto che ha responsabilità su una singola parte della funzionalità invece di essere in grado di eseguire molte funzioni, a volte anche non correlate, rendendo questa classe ampia e strettamente accoppiata, quindi- chiamato "God object".

Inoltre ho descritto questi principi in maggior dettaglio nel mio post sul blog, per favore dare un'occhiata.

link

    
risposta data 28.04.2017 - 06:52
fonte

Leggi altre domande sui tag