Quelle est la différence entre le principe de responsabilité unique et la séparation des préoccupations


19

a) Quelle est la différence entre SRP et SoC ? Peut-être que SRP est appliqué au niveau de la classe, tandis que SoC peut être appliqué au niveau du système , du sous - système , du module , de la classe ou de la fonction .

b) Si la réponse à a) est oui, le SoC appliqué au niveau de la classe est -il synonyme de SRP ?

Merci

Réponses:


13

Le principe de responsabilité unique est que votre code ne fait qu'une seule chose et vous pouvez diviser toutes les fonctionnalités en plusieurs classes qui sont toutes destinées à faire 1 chose spécifique. Un exemple est une classe spécifique pour la validation, faire de la logique métier, enrichir un modèle, récupérer des données, mettre à jour des données, navigation, etc.

La séparation des préoccupations concerne le fait que votre code n'est pas étroitement couplé à d'autres classes / systèmes. L'utilisation d'interfaces dans votre code aide beaucoup, de cette façon, vous pouvez coupler de manière lâche les classes / systèmes à votre code. Un avantage de cela est qu'il est plus facile de tester également votre code. Il existe de nombreux frameworks (IoC) qui peuvent vous aider à y parvenir, mais vous pouvez également implémenter une telle chose vous-même.

Un exemple de quelque chose de SoC, mais sans 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();
    }
}

Comme vous pouvez le voir, ce code n'est pas étroitement couplé à des classes ou à d'autres systèmes, car il n'utilise que certaines interfaces pour faire des choses. C'est bon d'un point de vue SoC.

Comme vous pouvez le voir, cette classe contient également 3 méthodes privées qui font des choses fantaisistes. D'un point de vue SRP, ces méthodes devraient probablement être placées dans certaines classes qui leur sont propres. 2 d'entre eux font quelque chose avec la navigation, ce qui correspondrait à une classe d'INavigation. L'autre fait quelques calculs fantaisistes sur un élément, cela pourrait probablement être placé dans une classe IBusinessLogic.

Ayant quelque chose comme ça, vous avez tous les deux le SoC et le SRP en place:

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

Bien sûr, vous pourriez débattre si toute cette logique devrait être placée dans la GetDataAndNavigateSomewhereIfValidméthode. C'est quelque chose que vous devez décider vous-même. Pour moi, il semble que cette méthode fasse beaucoup trop de choses.


"Après avoir lu le post complet dans la réponse de JB King, je pense que c'est aussi un bon post." Mais la réponse de JB King réclame le contraire de votre réponse - à savoir que le SoC est également une question de responsabilité unique, seulement qu'il peut être appliqué à des niveaux supérieurs à SRP
user1483278

2

En ce qui concerne le SRP appliqué uniquement au niveau de la classe, dans ses livres, Robert C. Martin (pour autant que je sache qu'il a popularisé sinon proposé le concept) déclare:

Code propre, page. 138 : "Le principe de responsabilité unique (PRS) stipule qu'une classe ou un module doit avoir une et une seule raison de changer."

Dans Agile Principles, Patterns and Practices in C #, page 116 : "[...] et associez la cohésion aux forces qui font changer un module ou une classe".

Je souligne.

Dans APPP, il parle plus longuement de SRP et se concentre presque entièrement sur le niveau de la classe. Bien qu'il semble se concentrer sur le niveau de la classe, je pense que le principe est également dirigé vers les modules et autres constructions de niveau supérieur.

Pour une telle raison, je ne qualifierais pas SRP de SoC au niveau de la classe comme vous le suggérez dans votre question.


Donc, si nous supposons que la SRP peut également être appliquée à des niveaux supérieurs, alors la différence entre la SRP et le SoC est que la SRP a une seule responsabilité, tandis que la SoC peut avoir un ensemble de responsabilités étroitement liées?
user1483278

@ user1483278: Eh bien, je connais très bien SRP, mais j'ai entendu parler de SoC pour la première fois en lisant cette question, je ne peux donc pas répondre à la question dans votre commentaire. D'après la sémantique, il semble que la SRP consiste à avoir une responsabilité et des problèmes de séparation du SoC, je sais que c'est une réponse pédante, mais dans les principes d'application, les résultats donnent des résultats similaires.
Gilles

0

Vous trouverez ici une courte vidéo expliquant clairement la différence entre ces terminologies. https://www.youtube.com/watch?v=C7hkrV1oaSY

Séparation des préoccupations (SoC). Divisez votre application en fonctionnalités distinctes avec le moins de chevauchement de fonctionnalités possible. (Microsoft).

"Concern" = "caractéristique distincte" = "section distincte"

«Concern» fonctionne à des niveaux élevés et faibles

Le principe de responsabilité unique stipule que chaque module ou classe doit avoir la responsabilité d'une seule partie des fonctionnalités fournies par le logiciel, et que la responsabilité doit être entièrement encapsulée par la classe. Tous ses services devraient être étroitement alignés sur cette responsabilité. (Définition Wikipedia)

«Responsabilité» = «raison de changer»

changer quoi? «Une seule partie des fonctionnalités fournies par le logiciel» = Unité de base

Conclusion

Le principe de responsabilité unique fonctionne sur les unités de base -> fonctionne à bas niveau

La séparation des préoccupations fonctionne à des niveaux élevés et faibles

SRP et SoC travaillent ensemble pour séparer les préoccupations. Ils sont exactement les mêmes à bas niveau


0

Voici ma compréhension de ces principes.

La séparation des préoccupations (SoC) - consiste à diviser un système logiciel en modules plus petits, chacun de ces modules est responsable d'une seule préoccupation. Une préoccupation, dans ce cas, est une fonctionnalité ou un cas d'utilisation d'un système logiciel. Un module possède une API (interface) bien définie, ce qui rend l'ensemble du système très cohérent. Il existe deux types principaux: horizontal et vertical.

Principe de responsabilité unique (SRP) - est un principe de conception qui stipule que chaque bloc de construction (il peut s'agir d'une classe, d'un module, d'un objet ou même d'une fonction) d'un système ne devrait avoir qu'une seule responsabilité. Robert C. Martin. Martin décrit une responsabilité comme une raison de changer. En général, il est préférable d'avoir une seule classe / un seul objet qui a la responsabilité d'une seule partie de la fonctionnalité au lieu de pouvoir exécuter un grand nombre de fonctions, parfois même sans rapport, ce qui rend cette classe grande et étroitement couplée, donc- appelé «objet de Dieu».

J'ai également décrit ces principes plus en détail dans mon article de blog, veuillez jeter un œil.

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.