Лучшая практика: порядок общественного / защищенного / частного в рамках определения класса? - PullRequest
71 голосов
/ 19 ноября 2009

Я начинаю новый проект с нуля и хочу, чтобы он был чистым / имел хорошие стандарты кодирования. В каком порядке опытным разработчикам здесь нравится выкладывать вещи в классе?

A: 1) публичные методы 2) приватные методы 3) публичные переменные 4) приватные переменные

B: 1) публичные переменные 2) частные переменные 3) открытые методы 4) закрытые методы

C: 1) публичные переменные 2) открытые методы 3) частные методы 4) частные переменные

Я обычно хотел бы ставить общедоступные статические переменные вверху, но тогда будет ли публичный статический метод указываться перед вашим конструктором, или конструктор всегда должен быть первым? Такого рода вещи ...

Я знаю, что это странно, но я просто удивился: каковы лучшие практики для этого?

PS: нет, я не использую Cc #. Я знаю. Я луддит.

Ответы [ 10 ]

113 голосов
/ 19 ноября 2009

В Чистый код , Роберт С. Мартин советует кодировщикам всегда помещать переменные-члены в начало класса (сначала константы, а затем закрытые члены), а методы должны быть упорядочены таким образом, чтобы они читайте как историю, которая не заставляет читателя слишком часто прыгать по коду. Это более разумный способ организации кода, а не модификатор доступа.

43 голосов
/ 19 ноября 2009

Лучшей практикой является быть последовательным .

Лично я предпочитаю сначала ставить методы public, затем методы protected и методы private. Участник data в общем случае всегда должен быть закрытым или защищенным, если только у вас нет веских причин для этого.

Мое обоснование для размещения методов public наверху состоит в том, что он определяет интерфейс для вашего класса, поэтому любой, кто просматривает ваш заголовочный файл, должен иметь возможность немедленно увидеть эту информацию.

Как правило, члены private и protected менее важны для большинства людей, просматривающих заголовочный файл, если только они не рассматривают возможность изменения внутренних элементов класса. Хранение их «в стороне» гарантирует, что эта информация поддерживается только на основе необходимости знать , один из наиболее важных аспектов инкапсуляции.

7 голосов
/ 19 ноября 2009

Я думаю, что у меня другая философия, чем у большинства. Я предпочитаю группировать связанные элементы. Я терпеть не могу прыгать, чтобы работать с классом. Код должен передаваться, и использование довольно искусственного упорядочения, основанного на доступности (общедоступном, частном, защищенном и т. Д.) Или экземпляре в сравнении со статическим или в виде члена или свойства в зависимости от функции, не помогает поддерживать хороший поток. Поэтому, если я добавлю открытый метод Method, который реализуется частными вспомогательными методами HelperMethodA, HelperMethodB и т. Д., То вместо того, чтобы эти методы были удалены друг от друга в файле, я буду держать их близко друг к другу. Точно так же, если у меня есть метод экземпляра, который реализован статическим методом, я тоже сгруппирую их.

Так что мои занятия часто выглядят так:

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 голосов
/ 19 ноября 2009

Лично мне нравится быть публичным наверху, защищенным, а затем приватным. Причина этого в том, что когда кто-то взламывает заголовок, он / она сначала видит то, к чему он / она может получить доступ, а затем прокручивает дополнительные сведения.

4 голосов
/ 19 ноября 2009

Это будет мой заказ

  1. Статические переменные
  2. Статические методы
  3. Публичные переменные
  4. Защищенные переменные
  5. Частные переменные
  6. Конструкторы
  7. Публичные методы
  8. Защищенные методы
  9. Частные методы

Я использую следующие правила:

  • статично перед чем-либо
  • переменные перед конструкторами перед методами (я считаю, конструкторы, чтобы быть в категории методы)
  • публично, прежде чем защищено, прежде чем приватно

Идея состоит в том, что вы определяете объект (данные) перед поведением (методами). Статика должна быть отделена, потому что она не является частью объекта или его поведения.

3 голосов
/ 19 ноября 2009

Раньше я много заботился. За последние несколько лет, используя современные интегрированные среды разработки, почти все находятся всего в 1 или 2 нажатиях клавиш, и я позволил своим стандартам существенно расслабиться. Теперь я начну со статики, переменных-членов, затем конструкторов, после чего я не буду сильно беспокоиться об этом.

В C # я разрешаю Resharper организовывать вещи автоматически.

2 голосов
/ 19 ноября 2009

Я в целом согласен с открытым, защищенным, частным порядком, а также со статическими данными, данными членов, порядком функций членов.

Хотя иногда я группирую похожих участников (получателей и установщиков), я обычно предпочитаю перечислять членов в группе АЛФЕБЕТИЧЕСКИ, чтобы их было легче найти.

Мне также нравится выравнивать данные / функции по вертикали. Я переместил / пробел вправо так, чтобы все имена были выровнены в одном столбце.

1 голос
/ 19 ноября 2009

Каждому свое, и, как говорит Эльзо, современные IDE упростили поиск членов и их модификаторов простым способом с цветными значками в выпадающих меню и т.п.

Мое предположение состоит в том, что для программиста важнее знать, для чего предназначен класс, и как можно ожидать его поведения.

Итак, если это Singleton, я сначала ставлю семантику (статический класс getInstance ()).

Если это конкретная фабрика, я сначала ставлю функцию getNew () и функции register / initialize.

... и так далее. Когда я говорю сначала, я имею в виду вскоре после c'ors и d'tor - так как они являются стандартным способом создания экземпляров любого класса.

Далее следуют следующие функции:

  1. логический порядок вызовов (например, initialize (), preProcess (), process (), postProcess ()) или
  2. связанные функции вместе (например, средства доступа, утилиты, манипуляторы и т. Д.),

в зависимости от того, предназначался ли класс в первую очередь как хранилище данных с некоторыми функциями или как поставщик функций с несколькими членами данных.

0 голосов
/ 11 ноября 2017

Последовательность public, за которой следуют защищенные и приватные, более читабельна для меня. Лучше просто описать логику класса в комментариях в верхней части файла заголовка и в порядках вызова функций, чтобы понять, какая доза класса и алгоритмы используются внутри.

Я некоторое время пользуюсь Qt c ++ и вижу новые типы ключевых слов, такие как signal и slot. Я предпочитаю продолжать заказывать, как указано выше, и делиться своей идеей с вами здесь.

#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 голосов
/ 19 ноября 2009

Некоторые редакторы, такие как Eclipse и его потомки, позволяют вам изменять порядок в виде структуры и методов в алфавитном порядке или на странице.

...