Лучшая практика: упорядочивание общедоступного / защищенного / частного в определении класса?

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

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

B: 1) общедоступные вары 2) частные вары 3) общедоступные методы 4) частные методы

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

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

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

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


person tempname    schedule 19.11.2009    source источник
comment
Нет ничего плохого в том, чтобы не использовать C #. За все годы работы профессиональным разработчиком я ни разу не написал ни строчки на C #. Используйте тот язык, который подходит для задачи, и скажите любому, кто говорит что-то другое, куда они могут пойти!   -  person Ether    schedule 19.11.2009
comment
Возможный дубликат stackoverflow.com/questions/150479/   -  person Michael Freidgeim    schedule 29.04.2013


Ответы (10)


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

person Asaph    schedule 19.11.2009
comment
Мне также повезло с добавлением: последние геттеры / сеттеры. Мне это помогает сделать занятия менее громоздкими. - person Dean J; 27.11.2009
comment
А как насчет конструкторов? - person VitalyB; 30.11.2014
comment
Конструкторы вверху, сразу после переменных-членов. В ООП выполнение начинается с создания экземпляра объекта. - person Asaph; 01.12.2014
comment
@ Асаф, ты помнишь эту главу? - person 2xMax; 01.12.2014
comment
Что, если вы инициализируете поле функцией? Означает ли это, что некоторые функции должны быть над полями? Что лучше: последовательность или удобочитаемость? - person VitalyB; 05.01.2015
comment
Принуждение читателя слишком много прыгать по коду, вероятно, должно быть сбалансировано с принуждением читателя прочитать все мельчайшие детали частных методов. Газетная метафора, вероятно, неправильно понимается в том смысле, что ваши общедоступные методы должны широко представлять то, что делает ваш класс, а ваши частные методы предоставляют детали (почти как сноска, на которую вы можете ссылаться, если вам нужно). - person Kenny Hung; 26.10.2015
comment
Я смущен. Вы сказали: (сначала константы, затем частные члены). В ПОРЯДКЕ. Куда же тогда деваются представители общественности? - person Honey; 06.09.2018
comment
@Honey Они пойдут сразу после констант и частных членов. Это будет в следующем порядке: константы, частные члены, публичные члены. - person Pierre Gillet; 27.02.2019
comment
Нет, К. Мартин строго этого не говорит. он говорит, помещайте их наверху, но это может зависеть от языка. Важно разместить их там, где их ожидают. Java: вверху (все его примеры на java), C +++ в конце. И он не делает никаких предположений о константных, публичных или частных членах. он просто говорит о переменных экземпляра, когда в своей книге говорит о переменных всего класса. - person Blechdose; 02.07.2020

Лучше всего быть последовательным.

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

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

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

person LeopardSkinPillBoxHat    schedule 19.11.2009
comment
LeopardSkikPBH, я полностью согласен ... в этом есть смысл! Думаю, я был сбит с толку относительно того, имеет ли в этом преимущество var или funcs. Спасибо! - person tempname; 19.11.2009
comment
Я не согласен с тем, что лучшая практика - быть последовательной. Есть много способов постоянно писать нечитаемый и некрашиваемый код. - person jason; 19.11.2009
comment
@ Джейсон, это все равно что сказать, что оставаться на своей стороне дороги - не лучшая практика, потому что там все равно могут быть аварии. - person Rex M; 19.11.2009
comment
@ Джейсон - Может, мне следовало быть более ясным. В этом конкретном, довольно субъективном случае (порядок методов) я думаю, что лучшая практика - быть последовательной. У каждого будет свое мнение о том, как лучше всего расположить вещи, но если вы по натуре последовательны, он должен быть достаточно удобным в обслуживании. Я согласен с тем, что быть последовательным - не всегда лучшая практика для всех областей кода, особенно если учесть плохое качество кода, с которым вам часто приходится иметь дело. - person LeopardSkinPillBoxHat; 19.11.2009
comment
@Rex M: Нет, то, что я сказал, совершенно не похоже на вашу интерпретацию. Я считаю, что простая последовательность в данном случае не является сильным аргументом. В некоторых случаях правильная последовательность (например, установка скобок). Но выбор здесь фактически влияет на читабельность кода. Таким образом, необходим аргумент более сильный, чем последовательность. - person jason; 19.11.2009

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

Не нужно смотреть на детали реализации класса, чтобы использовать его, тогда дизайн класса выполнен плохо.

person AndersK    schedule 19.11.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;
    }       
}
person jason    schedule 19.11.2009

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

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

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

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

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

person barkmadley    schedule 19.11.2009
comment
спасибо barkmadley ... это интересно! что вы поставили бы 4 и 5 перед конструктором. Я обязательно подумаю об этом - person tempname; 19.11.2009
comment
Как этот порядок, хотя наличие статических методов в верхней части интересно. Я работал с разработчиком, который помещал частные переменные внизу, я видел идею, но это не казалось правильным - person Carlton; 27.04.2018

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

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

person ScottS    schedule 19.11.2009
comment
Я согласен. Мой обычный способ навигации по элементам в файле - использовать инструмент, встроенный в любую IDE или редактор, который я использую. Фактическая группировка членов становится вторичной. Однако я согласен с тем, что участники должны быть сгруппированы, чтобы избежать чисто случайного упорядочения, и я использую resharper, чтобы группировать и упорядочивать автоматически. - person Phillip Ngan; 30.11.2009

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

Хотя я иногда группирую членов группы (получатели и сеттеры), я обычно предпочитаю перечислять членов внутри группы БУКВЕННО, чтобы их было легче найти.

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

person AlanKley    schedule 19.11.2009
comment
Эй, табуляция в моем собственном сердце! :-) Я не навязчивый. Честно говоря, нет! - person tempname; 19.11.2009

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

Я считаю, что программисту более важно знать, для чего был разработан класс и как от него ожидать поведения.

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

Если это конкретная фабрика, я сначала помещаю функцию getNew () и функции регистрации / инициализации.

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

Следующие ниже функции находятся в:

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

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

person Fox    schedule 19.11.2009

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

person Elzo Valugi    schedule 19.11.2009

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

Я использую 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
person saeed    schedule 11.11.2017