Найкраща практика: впорядкування публічного / захищеного / приватного в межах визначення класу?


92

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

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

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

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

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

Я знаю, що це фіннік, але я просто задався питанням: які найкращі практики для цього?

PS: ні, я не використовую Cc #. Я знаю. Я луддіт.


9
Немає нічого поганого, якщо не використовувати C #. Я ніколи не писав швів на C # за всі роки свого професійного розвитку. Використовуйте будь-яку мову, яка відповідає завданням, і скажіть кожному, хто каже щось інше, куди він може піти!
Ефір

1
Можливий дублікат stackoverflow.com/questions/150479 / ...
Michael Freidgeim

Відповіді:


143

У “ Чистому коді” Роберт К. Мартін радить кодерам завжди розміщувати змінні члени вгорі класу (спочатку константи, потім приватні члени), а методи слід упорядковувати таким чином, щоб вони читали як історію, яка не викликає читачеві потрібно занадто багато стрибати навколо коду. Це більш розумний спосіб впорядкувати код, а не за допомогою модифікатора доступу.


10
Мені також пощастило додати: getters / setters last. Мені це допомагає, щоб заняття почувалися менш громіздкими.
Дін Дж

5
Конструктори вгорі, відразу після змінних-членів. В ООП виконання починається з екземпляру об'єкта.
Асаф,

6
Причиняючи читача занадто багато стрибати навколо коду, мабуть, потрібно збалансувати, змушуючи читача читати всі дрібні деталі приватних методів. Газетна метафора, ймовірно, неправильно зрозуміла, оскільки ваші публічні методи повинні широко представляти те, що робить ваш клас, а ваші приватні методи надають деталі (майже як виноска, на яку ви можете звернутися, якщо вам потрібно).
Kenny Hung

1
Я збентежений. Ви сказали: (спочатку константи, потім приватні члени) . ГАРАЗД. Куди тоді йдуть представники громадськості?
Мед

1
@Honey Вони пішли б відразу за константами та приватними членами. Тож це було б у наступному порядку: Константи, приватні члени, публічні члени.
Pierre Gillet

48

Найкраща практика - бути послідовними .

Особисто я вважаю за краще ставити publicметоди спочатку, а потім protectedметоди, а потім privateметоди. Члени даних повинні взагалі завжди бути приватними або захищеними, якщо у вас є вагомі підстави для того , щоб не бути так.

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

Загалом, privateі protectedчлени менш важливі для більшості людей , дивлячись на файл заголовка, якщо вони не розглядають зміни внутрішніх елементів класу. Тримаючи їх "у стороні", гарантується, що ця інформація зберігається лише на основі необхідності знання , одного з найважливіших аспектів інкапсуляції.


LeopardSkikPBH, я повністю згоден ... це має сенс! Я думаю, я був заплутаний щодо того, чи всередині цього var або funcs мають пріоритет. Дякую!
tempname

11
Я не згоден з тим, що найкраща практика полягає в тому, щоб бути послідовними. Існує багато способів послідовно писати нечитабельний, незмінний код.
jason

3
@ Джейсон, це все одно, що казати, що не найкраща практика залишатися на узбіччі дороги, тому що там все одно можуть бути аварії.
Рекс М

1
@ Джейсон - Може, я повинен був бути більш чітким. У цьому конкретному, досить суб’єктивному випадку (упорядкування методів), я вважаю, що найкраща практика полягає у послідовності. У кожного буде думка про найкращий спосіб впорядкувати речі, але якщо ви послідовні за своєю природою, це повинно бути досить ремонтопридатним. Я погоджуюсь, що "бути послідовними" не завжди є найкращою практикою для всіх областей коду, особливо якщо ви враховуєте низьку якість коду, з якою вам часто доводиться мати справу.
LeopardSkinPillBoxHat

4
@Rex M: Ні, те, що я сказав, зовсім не схоже на вашу інтерпретацію. Моя думка полягає в тому, що лише послідовність не є вагомим аргументом у цьому випадку. У деяких випадках узгодженість є доброю (наприклад, розміщення брекетів). Але вибір тут насправді впливає на читабельність коду. Таким чином, потрібен аргумент, сильніший за послідовність.
jason

8

Думаю, у мене є інша філософія щодо цього, ніж у більшості. Я волію групувати пов’язані предмети разом. Я терпіти не маю необхідності стрибати, щоб працювати з класом. Код повинен текти, і використання досить штучного впорядкування, заснованого на доступності (загальнодоступному, приватному, захищеному тощо) або екземплярі проти статичного, або член проти властивості проти функції, не допомагає зберегти хороший потік. Так що, якщо я неф публічного методу , 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;
    }       
}

8

Особисто мені подобається мати публічне зверху, захищене, а потім приватне. Причиною цього є те, що коли хтось розкриває заголовок, він / вона бачить, до чого він / вона може отримати доступ спочатку, а потім більше деталей, коли він / вона прокручує вниз.

Не слід дивитися на деталі реалізації класу, щоб використовувати його, тоді дизайн класу не зроблений належним чином.


3

Раніше я багато піклувався. Протягом останніх кількох років із використанням сучасних IDE майже все залишається лише на 1 або 2 натискання клавіш, я дозволив своїм стандартам значно розслабитися. Тепер я починаю зі статики, змінних-членів, потім конструкторів, після чого я сильно про це не турбуюся.

У C # я дозволяю Resharper організовувати речі автоматично.


Я згоден. Моїм звичайним режимом навігації за членами у файлі є використання інструменту, вбудованого в будь-яку IDE або редактор, який я використовую. Фактичне групування членів стає другорядним. Однак я погоджуюсь, що члени повинні бути згруповані, щоб уникнути чистого випадкового впорядкування, і я використовую resharper, щоб робити групування та впорядкування автоматично.
Філіп Нган,

2

Це було б моє замовлення

  1. Статичні змінні
  2. Статичні методи
  3. Відкриті змінні
  4. Захищені змінні
  5. Приватні змінні
  6. Конструктори
  7. Публічні методи
  8. Захищені методи
  9. Приватні методи

Я використовую наступні правила:

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

Ідея полягає в тому, що ви визначаєте об'єкт (дані) перед поведінкою (методами). Статику потрібно відокремлювати, оскільки вона насправді не є частиною об’єкта, ані його поведінка.


спасибі barkmadley ... це цікаво! що ви поставите 4 і 5 перед конструктором. Я точно подумаю над цим
tempname

Як цей порядок, хоча статичні методи вгорі цікаві. Я працював з розробником, який розміщував приватні змінні внизу, я міг бачити ідею, але це не було добре
Карлтон,

2

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

Хоча я іноді групую учасників, як учасники (геттери та сетери), я, як правило, волію перерахування членів групи в алфавіті, щоб їх було легше знайти.

Мені також подобається виставляти дані / функції по вертикалі. I вкладка / пробіл праворуч, щоб усі імена вирівнювалися в одному стовпці.


1
Гей - "прокладка табуляції" після мого власного серця! :-) Я не нав’язливо-компульсивний. Чесний я ні!
tempname

1

Кожному своє, і як каже Ельзо, сучасні середовища розробки спростили пошук членів та їх модифікаторів простим способом за допомогою кольорових піктограм у випадаючих меню тощо.

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

Отже, якщо це синглтон, я насамперед ставлю семантику (статичний клас getInstance ()).

Якщо це бетонна фабрика, я спочатку ставлю функцію getNew () та функції реєстрації / ініціалізації.

... і так далі. Коли я кажу перший, я маю на увазі незабаром після c'tors і d'tor - оскільки вони є типовим способом створення будь-якого класу.

Далі виконуються функції, які:

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

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


0

Деякі редактори, такі як Eclipse та його нащадки, дозволяють змінювати порядок у контурному перегляді варіантів та методів за алфавітом або як на сторінці.


0

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

Я деякий час використовую 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.