Чи я аморальний за те, що використовую ім'я змінної, яке відрізняється від свого типу лише в регістрі?


95

Наприклад, візьмемо цей фрагмент коду:

var person = new Person();

або для вас Pythonistas:

person = Person()

Мені постійно говорять, як це погано, але я ще не бачив прикладу аморальності цих двох рядків коду. Для мене людина - це Особа, і намагатися дати їй інше ім’я - марна трата часу. Гадаю, за часів до підсвічування синтаксису це було б великою справою. Але в наші дні досить легко відрізнити ім’я типу, крім імені змінної. Чорт, навіть легко побачити різницю тут на SO.

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


Я завжди дивувався з цього приводу. Приємне запитання!
Вільям Брендель

18
Виклик людини-людини просто жорстокий. Що поганого в "бобі"?
Сем Мелдрум

17
Не забуваємо раніше, як var була дзен-краса Person person = new Person ();
Jamie Ide

1
@Jamie ти дзвониш статичним набором дзен-як?
orokusaki

Я хотів би ще глибше заглибитися у це питання: чи є, безперечно, неправильно робити Person Person=new Person();це питання? Як зазначено у "Питанні", ми живемо в часи такого неймовірного висвітлення синтаксису та розпізнавання контексту, що мій компілятор ніколи не скаржився, що я роблю саме це. Мені просто подобаються мої змінні CamelCased - чому б і я цього не Person Personзробив (у ситуаціях, коли є загальний і єдиний екземпляр класу, і жоден конфлікт не присутній і не можливий)?
Роберт Синорадзкі

Відповіді:


94

Які міркування тих, хто каже вам, що це погано? Я роблю це постійно. Це найпростіший, виразний спосіб назвати одну змінну типу. Якщо вам потрібні два Personоб'єкти, тоді ви можете personдодати префікс із значущими прикметниками типу

fastPerson
slowPerson

інакше просто

person

мені добре.


8
"Яка аргументація тих, хто каже вам, що це погано?" - Невідомо. Тому я започаткував цю тему. :-)
Джейсон Бейкер,

Очевидно, вам ніколи не доводилося вводити чужий код. Я знаю, що коли мене закликають дослідити якусь нещодавно виявлену помилку в кількарічному коді програмістом, який давно покинув компанію, - все, що заважає мені нарощувати, - це час не вирішувати проблему. Якщо одна з цих перешкод намагається з'ясувати, що це за екземпляр і що це за клас, лише тому, що програміст не міг завадитись сказати "var currentPerson = New Person ();" то це марно, марно витрачений час. ... і коли ваші клієнти чекають виправлення, час має важливе значення.
Девід

3
@David - Ти схопив мене! Я знав, що кодування у вакуумі рано чи пізно призведе до його некрасивої голови :) Хоча серйозно - мені важко повірити, що ти потрапляєш у тріщину через неможливість розрізнити типи та їх екземпляри на основі цієї конвенції про іменування.
Andrew Hare

2
@David - це має бути проблемою для інструменту аналізу коду. Крім того, тому існує домовленість, що типи починаються з великої літери в Python.
ілля н.

69

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

Неправильно було б, якщо у вас є два типи Особа та людина, то це дуже дуже неправильно.


1
"Що буде неправильним, якщо у вас є два типи" Особа "та" Особа ", це дуже неправильно". - Для мене це цілком сенс.
Джейсон Бейкер,

1
Якщо ваша побудова API VB не зможе обробляти код, оскільки він не враховує регістр.
JoshBerke

1
Гей, у випадку з API вас турбують імена чи властивості загальнодоступних методів, а не імена змінних, оскільки останні не будуть піддані дії клієнтського коду. Що стосується питання Джейсона, я теж весь час використовую це найменування. Абсолютно нічого страшного в цьому немає.
Фредерік-дурень,

1
Саме так, Фредерік, чому наявність двох типів, які відрізняються лише базовим регістром, є поганою ідеєю ;-)
JoshBerke

1
Навіть якщо це не неправильно, це ускладнює читання коду. Читаність теж має значення.
J3r3myK

45

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

Person person = new Person(); // okay

int Int = 42; // pure evil

Якби насправді не було семантичного значення, я міг би надати примітив, я б використовував i або s, крім індексів циклу, я не можу думати про будь-який інший такий сценарій.
AnthonyWJones

1
Я б не рекомендував використовувати i, особливо якщо ви пишете код із циклом. i майже повсюдно розглядається як ім'я змінної циклу.
Джейсон Бейкер,

3
Домовились. Однобуквене ім'я змінної кричить "Я тимчасовий". Індексами циклу повинні бути i, j, k, будь-які інші - a, b, c, x, y, z або будь-яка інша буква, яку не можна помилково прийняти за щось інше, наприклад l та o.
Білл Ящірка

браво! 42 - це просто занадто. :)
Vishal Seth

18

Якщо хтось каже, що це зло, запитайте їх, чи це краще:

var abc = new Person();

2
@Chris: саме так! Або ще краще: var temp = new Person();(Застереження: я знаю, що насправді є місця для одночасного використання тимчасових змінних, але як часто, коли я не бачу це в чиємусь коді, автор просто так і не повернувся, щоб дати var відповідному імені, і це може також бути "abc".)
Діна,

15

Якщо Людина є загальною Особою в контексті, то "людина" - це справді гарне ім'я. Звичайно, якщо Особа має певну роль у коді, тоді краще назвати її за допомогою ролі.


9

Думаю, за це я отримаю голос, але ...

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


6
Як варіант, якщо моральні рішення, які ми можемо прийняти, є такими незначними, ми прокляті. Я не впевнений, що хочу, щоб мій похоронний панегірик концентрувався на моєму стилі кодування. Я хотів би хоча б коротко згадати про те, що я є частиною сім'ї.
Девід Торнлі,

1
@David: Ще раз. З моїм першим онуком у дорозі, я гадаю, це банально, але мені все одно, який світ ми передаємо.
Mike Dunlavey

8

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


6

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

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

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


6

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

Person person = новий Person ();

Person person2 = new Person ();

Тоді це межувало б із "Поганим". Однак у такому випадку вам слід зробити рефакторинг своєї первісної особи, щоб розрізнити їх.

Що стосується вашого прикладу, ім'я змінної "людина" є ідеально описовою назвою для об'єкта "Особа". Тому в ньому немає нічого поганого.


3

Я називаю ім’я, що це таке: якщо змінна представляє людину з 2 собаками, назвіть це personWith2Dogs. Це змінна має короткий обсяг (як цикл var), тоді людина добре.


3

Я багато використовую це у своєму коді, і не думаю, що в ньому щось погане. Тим не менш, я (мабуть) не використовував би його в методі довше, ніж, скажімо, на одному екрані, і якщо є кілька екземплярів класу Person. Однозначно не називайте їх person1, person2, person3 ... замість цього використовуйте щось більш описове, наприклад person_to_del, person_to_ban, person_to_update тощо.


3

Не аморально, але глобальний пошук знайде і те, Personі інше, personякщо не вдасться активувати чутливість до регістру. Я віддаю перевагу префіксу, щоб спростити глобальний пошук / заміну, але абсолютно НЕ угорський чи щось довге / складне. Отже, я використовую ...

Personдля класу / типу aPersonдля локальної змінної thePersonдля параметра методу myPersonдля змінної екземпляра ourPersonдля змінної класу

У рідкісних випадках я міг би використовувати pв локальному контексті, де у мене є БАГАТО посилань, але це зазвичай стосується лише індексів циклу тощо.


3

Це залежить.

Якщо у вас строгий стиль написання великих літер, тому змінні починаються з малої літери (а для розривів слів використовуються або under_scores, або camelCase), а класи починаються з великих літер, тоді очевидно, що людина є змінною, а Person - класом, і коли хтось це розуміє , здається, вони не будуть знаходитись в перекриваються просторах імен. (Подібним чином, люди майже ніколи не плутаються між дієсловом або іменником «польський» та прикметником «польський».)

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


Знову привіт Девід. Я не пам’ятаю, чи редагували ви одне з моїх публікацій саме тому, що я написав "опитування", чи це було "польським", коли я мав на увазі щось терти, поки воно не засвітиться? Ну, я все ще не впевнений, що правильно :-)
Майк Данлавей,

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

2

Які саме аргументи використовують ці люди?

Якщо вони не дозволяють використовувати особу в якості імені змінної, ви можете додати префікс 'a'.

aPerson = Person()

2
На мою думку, це було б гірше. Його важче читати, і він не надає ніякої додаткової інформації.
Йоахім Зауер,

Так, але принаймні назва відрізняється від назви класу, чого очевидно вони хочуть.
Gerrie Schenck

Це було б слідуючи буквам закону, але точно не духу.
Йоахім Зауер,

1
+1, я використовую thePerson для параметрів та myPerson для місцевих жителів, якими я керую.
Емі Б,

2

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

Наприклад, я використовую lowerCamelCase для екземплярів, змінних та UpperCamelCase для класів тощо

Стандарти кодування повинні усунути цю проблему.

Коли я дивлюсь на успішні програми з відкритим кодом, вони часто мають стандарти кодування

http://drupal.org/coding-standards

http://help.joomla.org/content/view/826/125/

http://wiki.rubyonrails.org/rails/pages/CodingStandards

http://lxr.linux.no/linux/Documentation/CodingStyle

Погодження стандартів кодування має бути останньою битвою з цього приводу.

Насправді подивіться на запис у вікіпедії (з http://en.wikipedia.org/wiki/CamelCase )

Стиль програмування та кодування

Іноді для позначення меж слів рекомендується вказувати межі слів вказівками щодо стилю кодування для написання вихідного коду (наприклад, мовою програмування Mesa та мовою програмування Java). Рекомендації, що містяться в деяких з цих рекомендацій, підтримуються засобами статичного аналізу, які перевіряють дотримання вихідного коду.

Ці рекомендації часто розрізняють UpperCamelCase і lowerCamelCase, як правило, вказуючи, який сорт слід використовувати для конкретних видів сутностей: змінних, полів записів, методів, процедур, типів тощо.

Один із широко використовуваних стилів кодування Java вимагає, щоб UpperCamelCase використовувався для класів, а lowerCamelCase - для екземплярів та методів. [19] Визнаючи це використання, деякі середовища розробки, такі як Eclipse, реалізують ярлики на основі CamelCase. Наприклад, у функції допоміжного вмісту Eclipse введення лише великих літер слова CamelCase запропонує будь-який відповідний клас або назву методу (наприклад, введення "NPE" та активація вмісту може запропонувати "NullPointerException").

Оригінальна угорська нотація для програмування вказує, що абревіатура в нижньому регістрі для "типу використання" (не типу даних) повинна мати префікс перед усіма іменами змінних, а решта імені в UpperCamelCase; як така вона є формою lowerCamelCase. CamelCase - це офіційна конвенція щодо імен файлів на Java та для персонального комп'ютера Amiga.

Microsoft .NET рекомендує lowerCamelCase для параметрів та непублічних полів, а UpperCamelCase (він же "стиль Паскаля") для інших типів ідентифікаторів. [20]

Python рекомендує UpperCamelCase для назв класів. [21]

Реєстр NIEM вимагає, щоб елементи даних XML використовували UpperCamelCase, а атрибути XML - lowerCamelCase.

Не існує єдиної конвенції щодо включення великих абревіатур (переважно скорочень та ініціалізмів) до назв CamelCase. Підходи включають залишення цілого абревіатури у верхньому регістрі (наприклад, у "useHTTPConnection") і залишення лише першої літери у верхньому регістрі (наприклад, у "useHttpConnection").

Корпус верблюда аж ніяк не універсальний у обчислювальній техніці. Користувачі декількох сучасних мов програмування, зокрема тих, що входять до сімейств Ліспа і Форта, майже завжди використовують дефіси. Серед причин, які іноді наводяться, є те, що для цього не потрібно перекладати на більшості клавіатур, що слова є більш читабельними, коли їх розділяють, і що регістр верблюда може просто не бути надійно збереженим у мовах, що не чують до регістру чи складаються до регістру (наприклад, Common Lisp, який, хоча технічно чутлива до регістру мова, за замовчуванням канонізує (складає) ідентифікатори у верхній регістр).


2

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

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

  • Показник загальних обчислень, що висуваються до загальних методів: якщо ви виконуєте проміжні маніпуляції зі структурами даних у бізнес-методі, наприклад, потрібно дедуплікацію масиву користувачів, ви повинні мати змінні в обсязі з іменами типу users[]і deduplicatedUsers[]. Якщо ви перемістите дедуплікацію до утилітного методу, ви можете викликати метод Utils.dedup(array), а ви можете викликати дедуплікаційний масив deduplicatedArrayабо просто result.

  • Декомпілятори Java часто використовують таку схему для іменування локальних змінних (змінні екземпляра та класу зазвичай доступні в байт-коді, але локальні змінні - ні), і результати є більш читабельними, ніж можна було б очікувати, насправді часто більш читабельними, ніж першоджерело.

  • Див. Принцип Ларрі Уолла "Місцева неоднозначність - це нормально" - http://www.wall.org/~larry/natural.html .


2

Я б сказав, що ви, мабуть, маєте на увазі певне використання кожного разу, коли створюєте об'єкт. Сам тип дуже рідко відображає це використання.

Отже, якщо ви хочете створити новий контакт у програмі адресної книги, можливо, ви захочете викликати змінну newContact.

І якщо ви модульно тестуєте свій код, щоб перевірити поведінку Personоб’єктів без встановлених імен, можливо, ви захочете викликати їх unnamedPersonабо щось подібне.

Виклик цього просто personвідмовляється від великих шансів зробити свій код самодокументованим.


Називайте це анонімно! :)) var anonymous = new Person (); Або ще краще: var you_know_who = new Person (); :))
Вадим Фердерер

@ Вадим Фердерер var he_who_must_not_be_named = new Person();:? :-)
Platinum Azure

2

Тільки якщо ви програмуєте на VB6. У такому випадку те, що ви робите, є незаконним, але не аморальним.


1

Я теж це роблю, і я також не розумію, чому це повинно бути `` аморальним ''. Хоча я розумію, що це "може" іноді викликає заплутаність, але сьогодні у нас є IDE з підсвічуванням intellisense та синтаксисом, які гарантують, що (якщо ви помилитесь і посилаєтесь на свою змінну замість вашого класу, і навпаки), ви будете побачити вашу помилку досить швидко. І у нас також є компілятор. :)


1

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


1

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

Наприклад, якщо ви мали справу з обчисленням вартості певного товару в Інтернет-магазині, такий код не був би гарною формою:

Decimal _decimal = item.BaseCost + item.Tax;

Натомість рекомендується використовувати більш описове ім’я, наприклад, „_total” або „_cost”.


1

Єдина проблема, пов’язана з подібним, що я знайшов, полягає в тому, що ви хочете однакове ім’я для приватного учасника, а також публічної власності.

Якщо вони відрізняються лише у регістрі, це буде чудово працювати в чутливих до регістру мовах, таких як C #, але не у VB.NET.

Так, наприклад, у VB я б писав

Private _name As String

але

Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal Value As String)
        _name = Value
    End Set
End Property

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


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

Так, це те, що я тут ілюструю. Визначення локальної змінної, наприклад, „Затьмарити людину як нову особу”, було б непогано. Дуже (дуже) зрідка з компілятором VB виникає неоднозначність, і звичайного заспокійливого автоматичного використання великих літер не відбувається. Це хороший візуальний сигнал, що все не добре.
ChrisA

1

Не аморально, але якщо найкращою назвою для вашої змінної є назва типу, щось не так або ви просто робите доказ концепції чи щось подібне. Для мене ім'я змінної повинно посилатися на значення в бізнес-контексті, а не на мову програмування. Зрозуміти код буде складніше.


1

Я часто використовую Person person = new Person()себе. Зазвичай використовується в Java / C #.

Хоча в підсумку я вчора здивувався, чому

private enum DataType {NEW, OLD}

не працює в C # ...

Особливо бачачи , як ви можете використовувати String, string, Double, double, ... за бажанням в C #.


enum підтримує лише байт, sbyte, short, ushort, int, uint, long, ulong. тобто дробові числові типи значень
Кев

1
Person person = new Person()

чудово в моїй книзі.

Що стає жахливим, коли у вас є:

string Person;
string person;

Дуже легко змішати 2.


1

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

Що стосується типів CLR (int, string тощо), ви можете використовувати або String, або рядок (і т.д.) для оголошення типу, тому я б уникав використовувати щось на зразок

int Int = 0;
string String = "hi there";

1

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

fastPerson / slowPerson, як і вище, чудові ... вони описові та диференційовані від імені змінної типу ... але давай, людині, називаючи int "Int" було б просто ліниво.


1

Я б сказав, що це ніколи не аморально - це насправді лише ваше ім'я змінної базового рядка. Якщо ви не можете придумати кращої назви, назвати її за типом є гарним за замовчуванням. ( Лише для складних типів - для вбудованих типів це зло ) І багато часу насправді не існує кращої назви, бо ви не розумієте я не знаю нічого іншого про змінну. Як і при цьому методі

void SaveToDatabase(Person person) {...}

Про єдине, що ще можна розумно назвати людиною, - це person_to_saveщось подібне, що здається зайвим.

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

void AddToAccount(Account account, Person person)  {...}

ніж це

void AddToAccount(Account account, Person dependent)  {...}

Однак, будь ласка, будь ласка - дуже, будь ласка, не ставіть перед назвою типу "a" або "t". IE aPerson для "особи" або tPerson для "людини". Це надто складно і не додає багато, якщо взагалі має значення. Крім того, ви починаєте забруднювати область застосування безліччю змінних, які починаються з a або t, що може мінімізувати значення intelli-sense.


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

0

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

Person aPerson = new Person();

Мені здається, це робить код більш природним.


0

Абсолютно нічого страшного з цим не залежать від застережень, на які вказують інші (підсумовуючи тут для зручності): не робити це з примітивними типами, переробляти оригінальний екземпляр, якщо інший екземпляр буде доданий пізніше, не використовувати char-case для диференціації назв класів тощо.

Моє правило? Заяви в коді повинні читатися як прості англійські речення.

Person person = новий Person ();

Працівник співробітник = person.getRole (ПРАЦІВНИК);

Батьківський батько = person.getRole (PARENT);

person.getFullName ();

worker.getSalary ();

parent.getChildren ();

parent.getFullName (); // припускаючи шаблон декоратора під час гри

if (person.hasRole (EMPLOYEE)) {

  ...

}

І так далі.

Якщо область дії змінної обмежена (наприклад, метод інкапсуляції складає 10-15 рядків), я можу навіть використовувати 'p' замість 'person'. Коротші імена змінних менше відволікають увагу при спробі утримати контекст у своїй голові. Уникайте безоплатних префіксів, таких як "а" або (здригаючись) угорська нотація та її відгалуження. (Майте на увазі, я не маю нічого проти таких префіксів при використанні у відповідному контексті - C ++ / COM / ATL / Win32 API-код і т.д., де це допомагає підтримувати пряме призначення / типізацію).

Мої два (!) Біти :-)

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