Question

Je cherche quelques bons exemples de code qui constitue une violation du principe de responsabilité unique. Ne me montrer des exemples de livres ou des sites Web de l'oncle Bob puisque ceux-ci sont partout sur Internet, comme celui-ci:

interface Modem
{
    public void dial(String pno);
    public void hangup();
    public void send(char c);
    public char recv();
}
Était-ce utile?

La solution

La granularité de votre conception OO est une question de goût et peut-être inapropriée pour les autres. Ainsi, je ne regarderais pas des exemples de briser le principe de responsabilité unique dans une classe d'affaires logique, de discuter si elle a trop ou trop peu à faire.

A mon avis, les meilleurs exemples (avec les pires effets secondaires) viennent de briser la superposition de votre application. P.ex:.

  • Exécution d'une logique métier dans la couche d'accès aux données (dont la seule responsabilité devrait fournir l'accès de persistance à l'application)
  • Accès aux services d'affaires de (par) le modèle de domaine (dont la seule responsabilité devrait être de stocker plus de l'état de l'application)
  • Exécution d'une logique métier complexe dans la couche de vue (responsable de la présentation des données et l'entrée d'utilisateur)

Autres conseils

Voici un code d'un projet PHP que je devais prendre:

class Session
{
    function startSession()
    {
        // send HTTP session cookies
    }

    function activateUserAccount()
    {
        // query the DB and toggle some flag in a column
    }

    function generateRandomId()
    {}

    function editAccount()
    {
        // issue some SQL UPDATE query to update an user account
    }

    function login()
    {
        // perform authentication logic
    }

    function checkAccessRights()
    {
        // read cookies, perform authorization
    }
}

Je crois que cette classe ne waaay à beaucoup.

En fait, dans la plupart des langues OO que je l'ai utilisé, la classe Object haut niveau est un bon exemple. Dans Ruby, par exemple, la classe Object (ou plus précisément le mixin Kernel, qui se mélange dans Object) a 45 méthodes d'instance publiques. Maintenant, certains d'entre eux sont des alias, mais il y a encore obtenu d'être au moins 20, et ils sont de partout. Je peux facilement identifier au moins 5 responsabilités.

Maintenant, je ne veux pas prendre le Ruby. Il est mon langage de programmation favori. Voilà pourquoi je l'ai utilisé comme un exemple: parce que c'est la langue que je suis plus familier. Et je suis raisonnablement sûr que ce que je l'ai écrit à propos de Ruby applique 100% également au moins Java et .NET.

La moindre idée de SRP est de définir les responsabilités afin que votre mise en œuvre ne vient cette chose. Il est comme vous faire une règle (en donnant une classe un nom et une responsabilité), puis essayer de le suivre.

Donc, si vous ne suivez pas ce que vous êtes la soit ne définissant pas la règle correctement ou vous être incompatibles en mettant en œuvre (ou les deux, ce qui pourrait effectivement être le cas le plus courant).

Je trouve généralement les classes qui ne donnent pas d'essayer demi-décent à la définition d'une responsabilité unique ou principale bonne réputation d'être les meilleures violations. Ensuite, vous aurez juste à lire toute la classe pour essayer de déterminer s'il y a des responsabilités bien définies du tout.

Il est une question qualitative de déterminer les « responsabilités » d'une classe.
Il suffit de regarder un code de classe donnée, ne peut en aucune mesure nous donner une idée de la façon dont il gère son repsonsibility.
Il est très nécessaire, atleast selon mon expérience, de prendre en compte la façon dont les modifications des exigences de la classe se propagent à d'autres modules (ou comment les changements d'autres classes se propagent à cette classe).

@schmeedy donne une bonne explication de « briser la stratification du système », qui je pense est juste l'une des façons d'analyser « domaine de responsabilité ».

J'ai essayé de prendre la discussion peu plus loin. Mes tentatives sont de définir d'une manière quantitative la « responsabilité ».
Quelques discussions sur mon blog: http: // conception de principe -pattern.blogspot.in/2013/12/single-responsibility-principle.html

#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>

@interface Spreadsheet : NSObject

- (void)loadFromURL:(NSURL *)url;
- (void)saveToURL:(NSURL *)url;
- (void)drawTo:(CGRect*)targetArea withContext:(CGContextRef *)context;

@end

Je dirais que l'exemple ci-dessus viole la SRP.

Sur le visage de celui-ci, il est clair que la classe est responsable d'une chose: Spreadsheets. Il se distingue des autres entités dans le domaine des problèmes de gestion des documents tels que traitement de texte.

Cependant, tenez compte des raisons pour lesquelles l'objet feuille de calcul pourrait changer.

Il peut y avoir un changement du modèle sous-jacent de la feuille de calcul. Cela affecte la charge et enregistrer le code, mais n'affecteraient pas la feuille de calcul est tiré. Ainsi, la responsabilité de chargement / sauvegarde sont séparés des responsabilités de dessin. Notre classe a deux responsabilités.

Donc, si nous pensons à toutes les raisons raisonnablement prévisibles pour changer une classe, et voir que seules les méthodes particulières sur la classe seraient touchés, nous voyons l'occasion de prendre en compte une responsabilité d'obtenir une classe plus ciblée.

Une classe révisée serait:

@interface SpreadsheetEncoder

- (NSData *)encodedSpreadsheet:(Spreadsheet *)spreadsheet;
- (Spreadsheet *)spreadsheetFromEncodedData:(NSData *)data;

@end

@interface Spreadsheet2 : NSObject

- (NSData *)data;
- (instancetype)initSpreadsheetFromData:(NSData *)data;
- (void)drawTo:(CGRect*)targetArea withContext:(CGContextRef *)context;

@end

Comme les progrès de développement de produits, nous pouvons nous demander à nouveau « ce qui pourrait changer » et factoriser alors les classes pour les garder responsables pour une seule préoccupation. SRP est seulement par rapport au domaine du problème et notre compréhension de celui-ci à un moment donné.

SRP à mon avis se résume à demander «ce qui peut changer? et «ce qui serait touché. Quand « ce qui peut changer » cartes sur une seule chose qui est touché, vous avez des classes qui mettent en œuvre le principe SRP.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top