Qual é a diferença entre o princípio de responsabilidade única e a separação de preocupações

19

a) Qual é a diferença entre SRP e SoC ? Talvez o SRP seja aplicado no nível da classe, enquanto o SoC possa ser aplicado nos níveis do sistema , subsistema , módulo , classe ou função .

b) Se a resposta a ) for sim, o SoC aplicado no nível da classe é sinônimo de SRP ?

obrigado

user1483278
fonte

Respostas:

13

O Princípio de responsabilidade única é que seu código está fazendo apenas uma coisa e você pode dividir todas as funcionalidades em várias classes, todas destinadas a fazer uma coisa específica. Um exemplo é uma classe específica para validação, executando alguma lógica de negócios, enriquecendo um modelo, recuperando dados, atualizando dados, navegação, etc.

A Separação de Preocupações refere-se ao fato de seu código não estar totalmente acoplado a outras classes / sistemas. O uso de interfaces no seu código ajuda bastante, dessa forma você pode associar classes / sistemas livremente ao código. Um ponto positivo disso é que é mais fácil testar seu código também. Existem muitas estruturas (IoC) que podem ajudá-lo a conseguir isso, mas você também pode implementar isso também.

Um exemplo de algo SoC, mas sem ter 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();
    }
}

Como você pode ver, esse código não está totalmente acoplado a classes ou outros sistemas, porque usa apenas algumas interfaces para fazer as coisas. Isso é bom do ponto de vista do SoC.

Como você pode ver, essa classe também contém três métodos particulares, que fazem algumas coisas sofisticadas. Do ponto de vista do SRP, esses métodos provavelmente devem ser colocados em algumas classes próprias. 2 deles fazem algo com a navegação, o que caberia em alguma classe de navegação. O outro faz alguns cálculos sofisticados em um item, provavelmente isso pode ser colocado dentro de uma classe IBusinessLogic.

Tendo algo parecido com isto, vocês dois têm o SoC e o SRP no lugar:

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();
    }
}

Claro que você pode debater se toda essa lógica deve ser colocada no GetDataAndNavigateSomewhereIfValidmétodo. Isso é algo que você deve decidir por si mesmo. Para mim, parece que esse método está fazendo coisas demais.

Jan_V
fonte
"Depois de ler o post completo na resposta de JB King, acho que também é um bom post." Mas a resposta de JB Rei está reivindicando o oposto de sua resposta - ou seja, que SoC é também sobre a responsabilidade única, só que ele pode ser aplicado em níveis superiores aos SRP
user1483278
2

Quanto ao SRP ser aplicado apenas no nível de classe, em seus livros, Robert C. Martin (tanto quanto eu sei que ele popularizou se não apresentou o conceito) afirma:

Código limpo, página. 138 : "O Princípio da Responsabilidade Única (SRP) afirma que uma classe ou módulo deve ter um e apenas um motivo para mudar."

Em Princípios Ágeis, Padrões e Práticas em C #, página 116 : "[...] e relacione a coesão às forças que fazem com que um módulo , ou uma classe, mude".

Ênfase minha.

No APPP, ele fala mais sobre o SRP e se concentra quase inteiramente no nível da classe. Embora ele pareça se concentrar no nível da classe, sinto que o princípio também é direcionado a módulos e outras construções de nível superior.

Por esse motivo, eu não qualificaria o SRP como SoC no nível da classe, como você sugere na sua pergunta.

Gilles
fonte
Portanto, se assumirmos que o SRP também pode ser aplicado em níveis mais altos, a diferença entre o SRP e o SoC é que o SRP tem uma única responsabilidade, enquanto o SoC pode ter um conjunto de responsabilidades estreitamente relacionadas?
user1483278
@ user1483278: Bem, eu estou muito familiarizado com o SRP, mas ouvi falar do SoC pela primeira vez ao ler esta pergunta, por isso não posso responder à pergunta no seu comentário. Pela semântica, parece que o SRP trata de ter 1 responsabilidade e preocupações separadas de SoC, eu sei que é uma resposta pedante, mas, na aplicação, os princípios de incômodo produzem resultados semelhantes.
Gilles
0

Aqui você encontra um pequeno vídeo explicando claramente a diferença entre essas terminologias. https://www.youtube.com/watch?v=C7hkrV1oaSY

Separação de preocupações (SoC). Divida seu aplicativo em recursos distintos com o mínimo possível de sobreposição de funcionalidades. (Microsoft).

“Preocupação” = “característica distinta” = “seção distinta”

"Preocupação" funciona em níveis alto e baixo

O princípio de responsabilidade única declara que cada módulo ou classe deve ter responsabilidade sobre uma única parte da funcionalidade fornecida pelo software e que a responsabilidade deve ser totalmente encapsulada pela classe. Todos os seus serviços devem estar estreitamente alinhados com essa responsabilidade. (Definição da Wikipedia)

"Responsabilidade" = "motivo para mudar"

mudar o que? “Uma única parte da funcionalidade fornecida pelo software” = Unidade Básica

Conclusão

O princípio de responsabilidade única funciona em unidades básicas -> funciona em nível baixo

O Separation of Concerns funciona em níveis alto e baixo

SRP e SoC trabalham juntos para separar as preocupações. Eles são exatamente os mesmos em nível baixo

Marco Crispino
fonte
0

Aqui está o meu entendimento desses princípios.

Separação de preocupações (SoC) - trata-se de dividir um sistema de software em módulos menores, cada um desses módulos é responsável por uma única preocupação. Uma preocupação, nesse caso, é um recurso ou um caso de uso de um sistema de software. Um módulo possui uma API (interface) bem definida como resultado, tornando todo um sistema altamente coeso. Existem dois tipos principais: horizontal e vertical.

Princípio de responsabilidade única (SRP) - é um princípio de design que afirma que cada componente básico (pode ser uma classe, um módulo, um objeto ou até uma função) de um sistema deve ter apenas uma única responsabilidade. Robert C. Martin. Martin descreve uma responsabilidade como um motivo para mudar. Em geral, é muito melhor ter uma única classe / objeto que tenha responsabilidade sobre uma única parte da funcionalidade, em vez de ser capaz de executar muitas funções, às vezes até não relacionadas, tornando essa classe grande e fortemente acoplada. chamado "objeto de Deus".

Também descrevi esses princípios em maiores detalhes no meu blog, por favor, dê uma olhada.

https://crosp.net/blog/software-architecture/srp-soc-android-settings-example/

CROSP
fonte