web-dev-qa-db-fra.com

Meilleure pratique: classement du public / protégé / privé dans la définition de classe?

Je commence un nouveau projet à partir de zéro et je veux qu'il soit propre/ait de bonnes normes de codage. Dans quel ordre les développeurs chevronnés ici aiment-ils disposer les choses au sein d'une classe?

A: 1) méthodes publiques 2) méthodes privées 3) vars publics 4) vars privés

B: 1) vars publics 2) vars privés 3) méthodes publiques 4) méthodes privées

C: 1) vars publics 2) méthodes publiques 3) méthodes privées 4) vars privés

J'aime généralement mettre les variables statiques publiques en haut, mais une méthode statique publique serait-elle répertoriée avant votre constructeur, ou le constructeur devrait-il toujours être répertorié en premier? Ce genre de chose...

Je sais que c'est finnicky mais je me demandais simplement: quelles sont les meilleures pratiques pour cela?

PS: non je n'utilise pas Cc #. Je sais. Je suis un luddite.

74
tempname

Dans Clean Code , Robert C. Martin conseille aux codeurs de toujours mettre les variables membres en haut de la classe (constantes d'abord, puis membres privés) et les méthodes doivent être ordonnées de manière à ce qu'elles se lisent comme une histoire qui n'oblige pas le lecteur à trop sauter le code. C'est une manière plus sensée d'organiser le code plutôt que par modificateur d'accès.

116
Asaph

La meilleure pratique consiste à être cohérent.

Personnellement, je préfère placer les méthodes public en premier, suivies des méthodes protected, puis des méthodes private. Les données des membres doivent en général toujours être privées ou protégées, sauf si vous avez de bonnes raisons de ne pas en être ainsi.

Mon raisonnement pour mettre les méthodes public en haut est qu'il définit le interface pour votre classe, donc toute personne lisant votre fichier d'en-tête devrait pouvoir voir ces informations immédiatement.

En général, les membres private et protected sont moins importants pour la plupart des gens qui consultent le fichier d'en-tête, sauf s'ils envisagent de modifier les internes de la classe. Les garder "à l'écart" garantit que ces informations ne sont conservées que sur une base besoin de savoir, l'un des aspects les plus importants de l'encapsulation.

45

Personnellement, j'aime avoir du public au sommet, protégé puis privé. La raison en est que lorsque quelqu'un ouvre l'ouverture de l'en-tête, il/elle voit ce à quoi il/elle peut accéder en premier, puis plus de détails en faisant défiler vers le bas.

7
Anders

Je pense que j'ai une philosophie différente à ce sujet que la plupart. Je préfère regrouper les éléments associés. Je ne supporte pas d'avoir à sauter pour travailler avec une classe. Le code doit circuler et l'utilisation d'un ordre plutôt artificiel basé sur l'accessibilité (public, privé, protégé, etc.) ou l'instance contre statique ou membre contre propriété contre fonction n'aide pas à garder un flux agréable. Donc, si je possède une méthode publique Method qui est implémentée par des méthodes d'assistance privées HelperMethodA, HelperMethodB etc., alors plutôt que d'avoir ces méthodes loin les unes des autres dans le fichier, Je vais les garder proches les uns des autres. De même, si j'ai une méthode d'instance implémentée par une méthode statique, je les regrouperai également.

Donc mes cours ressemblent souvent à ceci:

class MyClass {
    public string Method(int a) {
        return HelperMethodA(a) + HelperMethodB(this.SomeStringMember);
    }

    string HelperMethodA(int a) { // returns some string }

    string HelperMethodB(string s) { // returns some string }

    public bool Equals(MyClass other) { return MyClass.Equals(this, other); }

    public static bool Equals(MyClass left, MyClass right) { // return some bool }

    public double SomeCalculation(double x, double y) {
        if(x < 0) throw new ArgumentOutOfRangeException("x");
        return DoSomeCalculation(x, y); 
    }

    const double aConstant;
    const double anotherConstant;
    double DoSomeCalculation(double x, double y) {
        return Math.Pow(aConstant, x) * Math.Sin(y) 
            + this.SomeDoubleMember * anotherConstant;
    }       
}
7
jason

Ce serait ma commande

  1. Variables statiques
  2. Méthodes statiques
  3. Variables publiques
  4. Variables protégées
  5. Variables privées
  6. Constructeurs
  7. Méthodes publiques
  8. Méthodes protégées
  9. Méthodes privées

J'utilise les règles suivantes:

  • statique avant tout
  • les variables avant les constructeurs avant les méthodes (je considère que les constructeurs sont dans la catégorie des méthodes)
  • public avant protégé avant privé

L'idée est de définir l'objet (les données), avant les comportements (méthodes). Les statiques doivent être séparées car elles ne font pas vraiment partie de l'objet, ni de son comportement.

4
barkmadley

J'aimais beaucoup. Au cours des dernières années, à l'aide d'IDE modernes, tout n'est qu'à une ou deux touches de distance, j'ai laissé mes normes se détendre considérablement. Maintenant, je commence par la statique, les variables membres, puis les constructeurs après cela, je ne m'en soucie pas beaucoup.

En C #, je laisse Resharper organiser les choses automatiquement.

3
ScottS

Je suis généralement d'accord avec l'ordre public, protégé et privé ainsi qu'avec l'ordre des données statiques, des données des membres et des fonctions des membres.

Bien que je groupe parfois comme des membres (getters & setters), je préfère généralement lister les membres d'un groupe ALPHABÉTIQUEMENT afin qu'ils puissent être localisés plus facilement.

J'aime aussi aligner les données/fonctions verticalement. Je tabule/espace assez à droite pour que tous les noms soient alignés dans la même colonne.

2
AlanKley

À chacun, et comme le dit Elzo, les IDE modernes ont facilité la recherche de membres et de leurs modificateurs de manière simple avec des icônes colorées dans les menus déroulants et autres.

Je pense qu'il est plus important pour le programmeur de savoir à quoi la classe a été conçue et comment on peut s'attendre à ce qu'elle se comporte.

Donc, s'il s'agit d'un Singleton, je mets d'abord la sémantique (classe getInstance () statique).

S'il s'agit d'une usine concrète, je mets d'abord la fonction getNew () et les fonctions register/initialize.

... etc. Quand je dis d'abord, je veux dire peu de temps après les c'tors et d'tor - car ils sont le moyen par défaut d'instancier n'importe quelle classe.

Les fonctions qui suivent sont alors dans:

  1. ordre d'appel logique (par exemple initialize (), preProcess (), process (), postProcess ()), ou
  2. les fonctions liées ensemble (comme les accesseurs, les utilitaires, les manipulateurs, etc.),

selon que la classe était principalement destinée à être un magasin de données avec certaines fonctions, ou un fournisseur de fonctions avec quelques membres de données.

1
Fox

Certains éditeurs, comme Eclipse et sa progéniture, vous permettent de réorganiser dans la vue d'ensemble les vars et les méthodes, par ordre alphabétique ou comme dans la page.

0
Elzo Valugi

La séquence de public suivi de protégé et privé est plus lisible pour moi, il est préférable de décrire la logique de la classe dans les commentaires en haut du fichier d'en-tête simplement et de faire fonctionner les ordres d'appels pour comprendre ce qu'une dose de classe et les algorithmes utilisés à l'intérieur.

J'utilise Qt c ++ depuis un certain temps et je vois une nouvelle sorte de mots clés comme signal et slot Je préfère continuer à commander comme ci-dessus et partager mon idée avec vous ici.

#ifndef TEMPLATE_H
#define TEMPLATE_H


class ClassName
{
    Q_OBJECT
    Q_PROPERTY(qreal startValue READ startValue WRITE setStartValue)
    Q_ENUMS(MyEnum)

public:

    enum MyEnum {
        Hello = 0x0,
        World = 0x1
    };

    // constructors

    explicit ClassName(QObject *parent = Q_NULLPTR);
    ~ClassName();

    // getter and setters of member variables

    // public functions (normal & virtual) -> orderby logic

public slots:

signals:

protected:

    // protected functions it's rule followed like public functions


private slots:

private:

    // methods

    // members

};

#endif // TEMPLATE_H
0
saeed