Які популярні «найкращі практики» не завжди є найкращими, і чому? [зачинено]


100

"Кращі практики" є всюди в нашій галузі. Пошук Google на «кодуванні кращих практик» з'являється близько 1,5 мільйона результатів. Ідея, здається, приносить комфорт багатьом; просто дотримуйтесь інструкцій, і все вийде нормально.

Коли я читаю про кращу практику - наприклад, нещодавно я читав декілька в « Чистому кодексі» - я нервую. Чи означає це, що я завжди повинен використовувати цю практику? Чи додані умови? Існують ситуації , в яких може НЕ бути хорошою практикою? Як я можу точно знати, поки не дізнаюся більше про проблему?

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

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

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

Я хотів би почути про конкретні приклади та досвід.


8
З якими практиками ви не згодні? Просто цікаво.
Серхіо Акоста

Будь-який автор може написати книгу, і я не повинен з цим погоджуватися - це так просто.
Робота

Одне, що мені подобається у книзі "Код завершений" Стіва МакКоннелла, це те, що він підкріплює всі свої поради твердими доказами та дослідженнями. Just sayin '
JW01

5
@Walter: Це відкрито місяцями, воно, безумовно, конструктивне, навіщо його закривати?
Увімкнення

2
Бачу, як тут згадується моє ім'я, я вважаю, що я повинен чіпнути: я вважаю, що відповіді тут цінні, але питання можна переробити в щось остаточно менш схоже на опитування, не скасовуючи жодної відповіді. Назва прикладу: "Які популярні" найкращі практики "іноді можуть бути шкідливими, і коли / чому?"
Aaronaught

Відповіді:


125

Я думаю, що ти вдарив цвяхом по голові цим твердженням

Мені б не хотілося сприймати речі за номінал і не думати про них критично

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

Реймонд Чен найкраще вказує в цій статті, коли говорить

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


4
Чудова цитата.
Девід Торнлі

Наступний абзац цієї цитати Реймонда Чена, ймовірно, описує угорські позначення! Більшість компаній, які я бачу, використовують його без реальних вагомих причин, які вони можуть пояснити.
Крейг

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

3
Обґрунтування добре. Дослідження краще.
Джон Перді,

7
Абсолютно правда, і я говорив те саме раніше. Мабуть, перший стандарт у будь-якому документі "Стандарти" повинен писати: "Для обміну знаннями та надання інформації, необхідної для скасування норм у пізніші терміни, усі стандарти повинні містити причини їх існування".
Скотт Вітлок

95

Можна також кинути це на ринг:

Premature optimization is the root of all evil.

Ні це не так.

Повна цитата:

"Ми повинні забути про невелику ефективність, скажімо, про 97% часу: передчасна оптимізація - корінь усього зла. Але ми не повинні пропускати свої можливості в цих критичних 3%".

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

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

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


4
+1 для сильних Ні, це не так.
Стівен

21
Але якщо ви вже визнали, що одна конкретна оптимізація знаходиться в межах критичних 3%, чи ви передчасні в її оптимізації?
Іоанн

7
@Robert: Тоді в чому сенс незгоди з твердженням, що "Передчасна оптимізація - корінь усього зла"?
Джон

8
Оптимізувати дизайнерські та технічні рішення на високому рівні, такі як вибір мови, не зарано. Однак часто лише після того, як ви в основному закінчили розробку дизайну, неефективність стає очевидною, саме тому Фред Брукс сказав, що більшість команд пише версію для викидання, чи мають намір вона чи ні. Ще один аргумент для прототипування.
Домінік МакДоннелл

8
@Robert, цитата Knuth була оптимізована передчасно ...

94

Одне повернення на функцію / метод.


7
Я збирався це поставити. Мені подобаються деякі заяви про раннє повернення.
Карсон Майєрс

4
Абсолютно! Люди створюють досить цікавий потік програми, щоб уникнути раннього returnтвердження. Або глибоко вкладені структури управління, або постійні перевірки. Це дійсно може роздути метод, коли a if returnдійсно може спростити цю проблему.
snmcdonald

4
Якщо вам потрібно кілька повернень у функції (окрім охоронців), ваша функція, ймовірно, занадто довга.
EricSchaefer

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

7
Я думаю, що це дуже застаріла найкраща практика. Я не думаю, що це найкраща сучасна практика.
Skilldrick

87

Не винаходити колесо - широко розповсюджена догма. Його ідея полягає в тому, що якщо існує відповідне рішення, використовуйте його замість того, щоб створювати своє власне; окрім економії зусиль, існуюче рішення, швидше за все, краще впроваджене (без помилок, ефективне, перевірене), ніж те, що ви б придумали спочатку. Все йде нормально.

Проблема полягає в тому, що 100% підходящий розчин рідко існує. Можливо, існує 80% рішення, і використовувати його, мабуть, добре. Але як приблизно 60% підходить? 40%? Де ви проводите лінію? Якщо ви не намалюєте лінію, ви можете ввімкнути включену в проект проектну бібліотеку, оскільки ви використовуєте 10% її функцій - просто тому, що ви хочете уникнути "винаходити колесо".

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


3
У мене це сталося навпаки. Я створив власний компонент сітки ajax, тому що в той час не було жодного, який би робив те, що я хотів, але згодом замінив його на сітки Ext JS. Це допомогло мені з самого початку припустити, що шар відображення буде замінений.
Joeri Sebrechts

20
Домовились. Якби ніхто ніколи не винаходив колесо, то ми б всі їздили на машинах на дерев’яних шинах.
Учень доктора Вілі

6
Я завжди відчуваю, як ваш 10% приклад, коли я додаю Boost до проекту C ++. Мені завжди потрібно менше 10%, безпосередньо, але, звичайно, функції мені потрібні для імпорту інших модулів, які імпортують інші модулі, які ...
Роман Старков

3
+1: лише цього тижня я перетворив колесо (наприклад, замінив роздутий, але популярний плагін jquery, який ми використовували чимось, що відповідає нашим потребам ще модульним), і це призвело до величезного підвищення продуктивності. Крім того, є люди, чия робота буквально винаходити колесо: наприклад, взяти Michelin, вони роблять НДДКР для покращення шин.
wildpeaks

2
@Лікар. Хитрі, ці колеса не були винайдені, вони були відновлені!

78

"Тест все."

Я чув, як це часто говорило, що всі коди повинні мати одиничні тести, з чим я не згоден. Коли у вас є тест на метод, будь-які зміни у виведенні чи структурі цього методу повинні бути внесені двічі (один раз у код, один раз у тесті).

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


7
Я підозрюю, що "Unit Test Everything" став кліше, як цитата "передчасна оптимізація". Я, як правило, погоджуюся з вашими пропорціями, і я бачив багато прикладів розробників, що проходять через монументальні зусилля, щоб знущатися над об'єктом додаткового рівня, зусилля, які можуть бути краще витрачені на тестування прийняття.
Роберт Харві

36
Якщо зміна структури методу викликає зміну ваших тестів, можливо, ви робите тестування неправильно. Блок тестів не повинен перевіряти виконання, а лише результат.
Адам Лір

7
@Anna Lear: Я думаю, що він говорив про внесення змін в конструкцію / структуру (рефакторинг). Оскільки дизайн недостатньо зрілий, коли ви знайдете кращий спосіб зробити це, можливо, вам доведеться змінити багато тесту в дорозі. Я погоджуюсь, що, коли ви більш кваліфікований тестер, ви можете легше помітити, де тест був би поганою ідеєю (через цю причину та інші), але якщо дизайн не дуже зрілий, ви все одно, швидше за все, матимете тести в шлях.
n1ckp

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

13
@ n1ck TDD насправді не є тестовою вправою стільки, скільки це вправою проектування. Ідея полягає в тому, що ви розробляєте свій дизайн за допомогою тестів (оскільки це швидко виявляє розумний API для ваших речей), а не підходить тести до існуючого дизайну (що може бути погано / недостатньо). Так що ні, вам не потрібно мати право проектування, щоб зробити тести спочатку.
Адам Лір

57

Завжди програмуйте на інтерфейси.

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


4
Погоджено, ви програмуєте на інтерфейс, коли вам потрібен інтерфейс (тобто стабільний API для роботи).
Роберт Харві

45
На моєму читанні це правило не стосується інтерфейсів, як мовних конструкцій. Це означає, що ви не повинні робити жодних припущень щодо внутрішнього функціонування класу під час виклику його методів, а покладатися лише на контракти API.
Zsolt Török

2
Добре, ось цікаве запитання - Я насамперед розробник .NET, тому для мене мої інтерфейси виглядають як IBusinessManager або IServiceContract. Для мене це надзвичайно просто орієнтуватися (і я, як правило, зберігаю свої інтерфейси в іншому просторі імен [або навіть іншому проекті]). Коли я використовував Java, я фактично виявив це заплутаним (як правило, реалізація інтерфейсу, яку я бачив, суфіксовано з .impl - і інтерфейси не мають розмежування). То це може бути проблемою стандартів коду? Звичайно, інтерфейси в java роблять код схожим - вони виглядають точно так само, як і звичайні класи на перший погляд.
Уотсон

5
@Watson: одна ціна полягає в тому, що кожного разу, коли я натискаю F3 ("перехід до декларації") на виклик методу в Eclipse, я переходжу до інтерфейсу, а не однієї реалізації. Потім мені доведеться керувати-T, стрілка вниз, повернутися, щоб перейти до реалізації. Він також блокує деякі автоматичні рефактори, наприклад, ви не можете вбудувати метод через визначення інтерфейсу, наприклад.
Том Андерсон

4
@Tom: Ну, сер, я з радістю втягнув би вас у цю війну, Eclipse vs. Intellij - однак у мене є видатний моральний кодекс, який заважає мені вступати у фізичні протистояння з кимось із очевидних негараздів. БУМ. Я не кажу, що Eclipse є поганим, я кажу, що якби сили Осі використовували його для створення або проектування своїх бойових машин, Друга світова війна була б відома як "Дводенна ярмарка". Якщо серйозно, то я виявив, що їй не вистачає певної лаки, яку я отримую в позачергових IDE (Intellij / VS + ReSharper). Я не раз стикався з цим, бо це занадто багато.
Уотсон

46

Не використовуйте нічого з відкритим кодом (або не для Microsoft для ваших розробників .NET)

Якщо Microsoft не розробила його - ми не використовуємо його тут. Хочете використовувати ORM - EF, хочете використовувати IOC - Unity, хочете увійти - блок застосунків журналу підприємств. Стільки кращих бібліотек існує - але я завжди дотримуюся замовлень із доларового меню світу розвитку. Я клянусь, щоразу, коли я чую кращі практики Microsoft, я думаю, що "рекомендації щодо харчувань McDonald's". Звичайно, ви, ймовірно, будете жити, якщо будете дотримуватися їх, але ви також будете недоїданими та зайвою вагою.

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

13
Звучить жахливо ... = (Я, мабуть, занадто багато з іншого боку, хоча я максимально уникаю M $.
Lizzan

Так не повинно бути. Бібліотеку слід вибирати за її цінністю, а не лише враховувати, хто її створив. Наприклад, я люблю EF, але у мене був поганий досвід роботи з бібліотекою Enterprise, і я знайшов кращі інструменти для перевірки та реєстрації даних, такі як FluentValidation, log4net та Elmah.
Маттео Моска

4
Ви не будете звільнені за покупку IBM ^ wMicrosoft
Крістофер Махан

17
Існує також версія дзеркального зображення, тобто ніколи не використовуйте нічого Microsoft або ніколи не використовуйте нічого, за що потрібно заплатити.
Річард Ґадсден

5
Мені пощастило працювати в організації, де це не широко розповсюджена догма, але в тих місцях, де ми прийняли комерційні рішення, там, безумовно, сильно болить. Проблема виникає тоді, коли якась частина комерційного рішення не дуже працює. Коли це відкритий код, ви можете подивитися джерело (кінцева документація) і дізнатися, що відбувається не так. З закритим джерелом ви повинні платити за привілей доступу до знань технічної підтримки, хто ще менше знає про продукт, який ви робите. І ось єдине доступне "виправлення".
SingleNegationElimination

40

Орієнтація на об'єкт

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


7
Я не уявляю, як створити програмну систему будь-якого значного розміру, не скориставшись організацією, яку забезпечує об'єктна орієнтація.
Роберт Харві

18
Роберт. Unix не є об'єктно-орієнтованою, і вона, безумовно, кваліфікується як програмна система значних розмірів. Це також здається досить популярним (думаю, Mac OSX, iPhone, телефони Android тощо)
Крістофер Махан

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

8
Срібної кулі немає. Функціональне програмування (Haskell) є досить успішним, не орієнтуючись на об'єкти. Зрештою, у вас є кілька інструментів, і ваша робота - підібрати найкращий асортимент під рукою завдання.
Матьє М.

9
Найсмішніше, що, крім використання класів, поліморфізму та подібних, більшість об'єктно-орієнтованих кодів насправді є процесуальним кодом.
Олівер Вайлер

35

Весь код слід коментувати.

Ні, цього не повинно бути. Деякий час у вас є очевидний код, наприклад, сетери не слід коментувати, поки вони не роблять щось особливе. Також, чому я повинен коментувати це:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
Весь код повинен бути зрозумілим . Коментарі є головним інструментом у цьому, але далеко не єдиним.
Тревель

Абсолютно код повинен бути зрозумілим. Але немає єдиної причини написати коментар, який нічого не додасть, наприклад, до назви методу. Якщо ви пишете, /** sets rank. */ void setRank(int rank) { this.rank = rank; }я вважаю коментар дурним. Чому це написано?
Володимир Іванов

2
Сформована документація. Ось для чого потрібний /** */формат, а не /* */коментар до формату. Або для .NET це було б///
Берін Лорич

10
Використовуючи }//end if, }//end for, }//end whileє найкращим прикладом марнотратного коментування я коли - небудь стикався. Я бачив це багато разів, коли вступна дужка знаходиться не більше ніж на 2 лінії вище. IMHO, якщо вам потрібні ці коментарі, тоді ваш код потребує повторного факторингу ... або вам потрібно заробити $ 20 та придбати редактор IDE / Text, який виділяє відповідні дужки.
scunliffe

7
Код сказати "як". У коментарях потрібно сказати "чому".

32

Методології, особливо scrum. Я не можу тримати прямо обличчя, коли чую, як дорослі люди використовують словосполучення "Scrum Master". Мені набридло чути, як розробники протестують, що якийсь аспект методології X не працює для їхньої компанії, щоб сказати лише Гуру «Так і тому», що причина не працює в тому, що вони насправді не є справжніми практиками методології X. "Побільше важче, ти повинен, мій учень Падаван!"

У гнучких методологіях існують самородки мудрості --- їх багато ---, але вони часто вкладаються в стільки гною, що я не можу боротися зі своїм клятим рефлексом. Візьміть цей шматочок зі сторінки scrum Wikipedia :

У Scrum визначено ряд ролей. Усі ролі поділяються на дві окремі групи - свині та кури - виходячи з характеру їх участі у процесі розвитку.

Дійсно? Свині та кури, кажете? Захоплююче! Не можу зачекати, щоб передати цей мій босу ...


Цікаво. Я згоден у такій мірі. З останньою частиною хоч: називай їх, що хочеш, вони мнемоніки, ось і все.
Стівен Еверс

12
+1 ... ти маєш рацію, важко сприймати це серйозно. <великий бурхливий голос> * Я СКРАММАСТЕР * </voice>
GrandmasterB

2
І притчі. Це нагадує мені про церковні проповіді, або про такі анекдоти, якими відомі гуру самодопомоги (і коміки): "Візьміть мого друга Стіва. Стів постійно сперечався зі своєю дружиною Шеріл. Ці двоє ходили на це годинами, щоб Тоді, одного разу ... "Такі дидактичні нитки не турбують мене в інших сферах, але мені дуже подобається бачити, як вони поширюються в технічних науках.
ухилення від потоку

2
Що з Scrum Ninjas?
Берін Лорич

1
Я не згоден зі порівнянням "Свині та курки" ... він летить прямо перед обличчям "Швидкого маніфесту". А саме "Співпраця з клієнтами щодо переговорів по договору". Клієнти настільки ж віддані (якщо не більше) успіху проекту, як команда проекту. Виклик одних ролей свиней та інших курей ролей створює менталітет "ми проти них", що ІМХО є найбільшою перешкодою для успішних проектів.
Майкл Браун

25

Реляційна карта об’єктів ... http://en.wikipedia.org/wiki/Object-relational_mapping

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


19
Передчасна оптимізація - корінь усього зла. Повільний код, в реальному житті, лише неймовірно рідко є проблемою порівняно з неможливим кодом. Використовуйте ORM, а потім проріжте абстракцію лише там, де вам це потрібно.
Fishtoaster

28
ORM - це інструмент 80-20. Вони призначені для обробки 80% CRUD, який стає таким стомлюючим, щоб через деякий час написати весь цей нескінченний код сантехніки. Інші 20% можна зробити більш "звичайними" способами, як-от використання збережених процедур та написання звичайних SQL-запитів.
Роберт Харві

18
@Fishtoaster: Ви не маєте на увазі: "Ми повинні забути про малу ефективність, скажімо, про 97% часу: передчасна оптимізація - це корінь усього зла. Але ми не повинні пропускати наші можливості в цих критичних 3%."
Роберт Харві

5
@Robert Harcey: Є причина, по якій я не використав пряму цитату. Я думаю, що більшість програмістів занадто багато фокусуються на ефективності - це проблема, яку мало кому потрібно вирішити. Справді, є певні домени, де це важливіше, ніж інші, але ремонтопридатність та розширюваність є проблемою скрізь. Ще одна змінена цитата: "Зробіть це роботою, зробіть його доступним для читання, зробіть його читабельним, зробіть його розширюваним, зробіть його тестувальним, а потім , якщо у вас є час, і виявиться, що вам це потрібно, зробіть це швидко".
Fishtoaster

12
@Craig: Як ти не розпізнав іронію у своїй заяві? Потрібен рік, щоб навчитися отримувати хороші показники з ORM - це відмінний аргумент проти ORM, як і необхідність "контролювати" вироблені SQL та вводити збережені процедури. Якщо у вас є знання для цього, ви маєте знання, щоб повністю обійти ORM.
Миколай Лицар

22

Написання імен функцій так, ніби вони були англійськими реченнями:

Draw_Foo()
Write_Foo()
Create_Foo()

і т.д. Це може виглядати чудово, але це біль, коли ви вивчаєте API. Наскільки простіше шукати в індексі "Все, що починається з Foo"?

Foo_Draw()
Foo_Write()
Foo_Create()

тощо.


2
Напевно, так само просто, як набрати Foo у списку функцій TM.
Джош К

68
Звучить так, що ви насправді хочете, щоб це було Foo.Draw(), Foo.Write()і Foo.Create(), щоб ви могли це зробити, Foo.methods.sortабоFoo.methods.grep([what I seek]).sort
Inaimathi

7
Починаючи з "Отримати" - ще один приклад.
JeffO

1
Я родом із світу objective-c і сильно пропускаю назви методів багатослівного введення та інфікування позначень, коли роблю java (моє інше життя). Оскільки заповнення коду почало працювати, я також не знайшов зайвої проблеми з набором тексту.

2
@Scott Уитлок: Чи не що з дати для деяких розробників .NET, IIRC, VS 2008 не зробив цього. 2010 рік хоч і є фантастичним.
Стівен Еверс

22

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

клас на базі ОО - на мій погляд, заохочує складні структури змінного стану. єдині переконливі випадки, які я виявив для ОО на основі класу протягом багатьох років, - банальні приклади "форма-> прямокутник-> квадрат", які утворюють главу 1 будь-якої книги OO


4
Я робив веб-розробки в ASP.NET і ASP.NET MVC, і, хоча MVC здається ешафот, я набагато віддаю перевагу над ASP.NET, з багатьох причин: простота, ремонтопридатність та надзвичайно тонкий контроль над розміткою. Все має своє місце, і хоча це все здається трохи повторюваним, підтримувати радість. Це повністю настроюється, тому якщо вам не подобається поведінка поза коробкою, ви можете змінити її.
Роберт Харві

1
Що стосується ОО, то існують хороші та погані способи зробити це. Спадщина завищена та використовується в реальному світі більш щадно, ніж вважає більшість книг; В даний час існує тенденція до більш функціонального, непорушного стилю розвитку навіть у світі ОО.
Роберт Харві

1
+1 для згадування MVC. У той час як концепція MVC (розділення логіки рівня даних, логіка подання та фонова логіка є хорошою ідеєю) фізично розділяти їх у складну ієрархію папок із мішаним файлом, що містить фрагменти коду, є дурним. Я звинувачую це у всіх явищах у відсутності підтримки PHP у просторі імен та розробників-новачків, що прославляють багаторічні методи як "новітню річ". Створити простір імен для аксесуарів бази даних, графічного інтерфейсу та фонової логіки (і просторів імен, де це потрібно) просто.
Еван Плейс

3
Що стосується ОО, то ви дійсно не побачите його переваг, поки ваш проект не виросте до того розміру, коли управління складністю стане важливим. Дотримуйтесь принципу єдиної відповідальності, де це можливо, і якщо ваш код доступний для публічного опромінення (наприклад, для .dll), приховуйте внутрішню реалізацію класів / методів / властивостей, де це можливо, щоб зробити код більш захищеним та спростити API.
Еван Плейс

1
Я особисто вважаю, що приклад shape-> rectangle-> square є одним з найелегантніших аргументів проти oop. наприклад, Square(10).Draw()йому достатньо Rectangle(10, 10).Draw(). тому я здогадуюсь, що це означає, що квадрат - це підклас прямокутника. Але mySquare.setWidthHeight(5,10)це нісенітниця (IE, вона не відповідає принципу заміни Ліскова), квадрат не може мати різну висоту і ширину, хоча прямокутник може, так що випливає, що прямокутник є підкласом квадрата. Це відомо і в інших контекстах як "Коло, проблема еліпса"
SingleNegationElimination

22

ЯГНІ

( Вам це не потрібно )

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

Мої ідеї часто відхилялися через YAGNI, і більшість випадків комусь доводилося платити за це рішення пізніше.

(Звичайно, можна стверджувати, що добре розроблена база коду також дозволить додавати функції згодом, але реальність інша)


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

12
P.Floyd, @Jason Baker: +1 Абсолютно правильно. Тут застосовується стара приказка "місяці в лабораторії можуть економити години в бібліотеці"
Стівен Еверс

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

1
@TokenMacGuy вирішальним аспектом є мається на увазі частина специфікації . Ось де думки сильно різняться.
Шон Патрік Флойд

20

Для SQL

  1. Не використовуйте тригери
  2. Завжди ховайте таблиці за видами

В порядку:

  1. Вони є особливістю, яка має своє місце. У вас є кілька шляхів оновлення до таблиці, або вам потрібен 100% аудит?

  2. Тільки чому? Я б, якби я відмовився від підтримки контракту, але не тоді, коли я прочитав, що фолк змінить погляд, щоб відповідати будь-яким змінам таблиці

Редагувати:

Число 3: Уникання * з ІСНУЮЧИМИ. Спробуйте 1/0. Це працює. Список стовпців не оцінюється відповідно до стандарту SQL. Сторінка 191


3
№2 - найкраща практика?
Хоган

2
@Hogan: Так, це документально підтверджено в багатьох місцях vyaskn.tripod.com/sql_server_security_best_practices.htm та flylib.com/books/en/3.404.1.34/1 І рідше тут: simple-talk.com/community/blogs/tony_davis/ архів /
2009/08/06

1
@Hogan: Вид, який просто відображає базову таблицю, не забезпечує безпеки над прямим використанням базової таблиці. Якщо ви приєднаєтесь до таблиці користувальницької безпеки або замаскуєте деякі стовпці, тоді досить справедливо. Але ВИБІРТЕ кожен стовпець із таблиці чи перегляду: різниці немає. Особисто я все-таки використовую збережені програми.
gbn

3
@Hogan: Я знаю щось про SQL Server :-) stackoverflow.com/users/27535/gbn Що я маю на увазі: GRANT SELECT на столі не відрізняється від GRANT SELECT ON VIEW, якщо подання SELECT * FROM TABLE
gbn

1
@gbn: Я згоден. Тут немає різниці. Я думаю, ми могли б сказати те саме. Я думаю, що мій оригінальний коментар ("№2 - найкраща практика?") Базувався більше на моєму особистому досвіді, що погляди (як тригери) частіше використовуються, ніж правильно. Таким чином, така найкраща практика призвела б лише до зловживань, а не до посилення. Якщо це вважається найкращою практикою, ви на 100% праві, це погана.
Хоган

20

В основному шаблони дизайну. Вони надмірно використані та недостатньо використані.


13
+1 Я досі не бачу, наскільки шаблони дизайну - це красиві чи елегантні рішення. Вони вирішують недоліки мови, не більше того.
Олівер Вайлер

2
Просто сприймайте це як намагання викорінювати мовний запах, використовуючи саму мову.
Філіп Дупанович

15

Принцип єдиної відповідальності

("кожен клас повинен мати лише одну відповідальність; іншими словами, кожен клас повинен мати одну, і лише одну, причину для зміни")

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

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

Уявіть, якби у творців API .Net був такий менталітет: а не List.Sort (), List.Reverse (), List.Find () тощо, ми мали б класи ListSorter, ListReverser та ListSearcher!

Замість того, щоб більше сперечатися проти СРП (що само по собі не є страшним в теорії) , я поділюся кількома моїми довгими анекдотичними переживаннями:


В одному місці, де я працював, я написав дуже простий вирішувач максимального потоку, який складався з п’яти класів: вузол, графік, графік-творець, графік-вирішувач і клас, щоб використовувати графік-творець / розв'язувачі для вирішення реальна проблема. Жоден не був особливо складним або довгим (вирішувач був на сьогодні найдовшим на ~ 150 рядків). Однак було вирішено, що в класах було занадто багато "обов'язків", тому мої колеги взялися за рефакторинг коду. Коли вони закінчилися, мої 5 класів були розширені до 25 класів, загальна кількість кодових рядків яких була більш ніж втричі вище, ніж вони були спочатку. Потік коду вже не був очевидним, а також не було метою нових одиничних тестів; Мені зараз важко було зрозуміти, що робив мій власний код.


Там же майже кожен клас мав лише єдиний метод (його єдина «відповідальність»). Слідкувати за потоком програми було майже неможливо, і більшість одиничних тестів складалися з тестування, яке цей клас називав кодом з іншого класу , обидва цілі якого для мене були однаково загадкою. Було буквально сотні занять, де мали бути (ІМО) лише десятки. Кожен клас робив лише одну "річ" , але навіть з умовами іменування типу "AdminUserCreationAttemptorFactory" було складно сказати взаємозв'язок між класами.


В іншому місці (у якому також були менталітети класів "повинен-мати-лише-один метод" ) ми намагалися оптимізувати метод, який займав 95% часу під час певної операції. Після (досить тупо) її оптимізації трохи я звернув свою увагу на те, чому його називали байліоном разів. Його називали в циклі в класі ... метод якого викликався в циклі в іншому класі .. який також викликався в циклі ..

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

У моєму проханні відновити ці 13 класи в один клас було відхилено.


6
Здається, що хтось отримав "Шаблон лихоманки" або в цьому випадку "Принципну гарячку" на цій роботі. Клас списку не порушує SRP. Усі його функції служать одній цілі, маніпулюючи колекцією предметів. Маючи лише одну функцію в класі, мені здається непосильним. Принцип, що стоїть за SRP, полягає в тому, що одиниця коду (будь то метод, клас чи бібліотека) повинна нести єдину відповідальність, яку можна заявити коротко.
Майкл Браун

3
Я почав бачити подібне божевілля від людей, які вважають неможливим написати чистий звичайний функціональний код. Занадто багато освіти, що кожну проблему в світі можна вирішити за допомогою книги шаблонів. Недостатньо думати про прагматизм. Як ви, я бачив якийсь клас на основі OO, такий жахливий, що слідувати за ним абсолютно неможливо. І його величезний і роздутий.
quick_now

3
Другий коментар тут. Багато "принципів" надмірно застосовуються. Є багато речей, які є гарними ідеями, де іноді доречно робити навпаки. ДОБРІ програмісти знають, коли порушують правила. Оскільки правила не є "правилами", вони є твердженнями про "добру практику" більшість випадків, за винятком випадків, коли це дійсно німа ідея ".
quick_now

"Уявіть, якби у творців API .Net був такий менталітет: а не List.Sort (), List.Reverse (), List.Find () тощо, ми мали б класи ClassSorter, ListReverser та ListSearcher ! ". Це саме те, що робиться в C ++, і це чудово . Алгоритми відокремлені від структури даних, тому якщо я записую власний контейнер, усі алгоритми, які працюють зі стандартною бібліотекою, просто працюють з моїм новим контейнером. Це повинно бути жахливо в .Net land, написавши нову функцію сортування для кожного нового контейнера, який ви хочете сортувати.
Манкарсе

14

Тепер, коли ви згадали «Чистий код», хоча він містить кілька хороших ідей, я думаю, що його нав'язливість перетворювати всі методи на підметоди і ті, які перебувають у підметодах і т. Д., Зайнята занадто далеко. Замість декількох десятирядкових методів ви повинні віддати перевагу двадцяти (нібито добре названих) одношарових. Очевидно, хтось думає, що це чисто, але мені це здається набагато гіршим, ніж оригінальна версія.

Також заміни простих елементарних речей, таких як

0 == memberArray.length

в межах класу з викликом до власного методу класу, такого як

isEmpty()

це сумнівне "поліпшення" ІМХО. Додавання: Різниця полягає в тому, що перша перевірка виконує саме те, що вона каже: перевіряє, чи довжина масиву дорівнює 0. Гаразд, isEmpty()може також перевірити довжину масиву. Але вона також може бути реалізована так:

return null != memberArray ? 0 == memberArray.length : true;

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


Це не означає, що розбивати довгі методи або брати участь у логічних порівняннях не годиться; Звичайно, це є, але в якій мірі це зробити - де солодке пляма - це, очевидно, питання смаку. Порушення довгого методу призводить до використання більше методів, і це не безкоштовно. Ви повинні стрибати навколо вихідного коду, щоб побачити, що насправді відбувається, коли ви могли це побачити з першого погляду, якби всі ці речі були в одному методі.

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


6
Я рідко бачу це як проблему. Переважно це тому, що я зазвичай бачу занадто багато в одному методі, не занадто мало. Однак, згідно з деякими дослідженнями, дуже низька складність методів також має дещо вищий рівень помилок, ніж помірно низька складність. enerjy.com/blog/?p=198
МВС

Так, це, безумовно, проблема лише в чистому коді. У реальному житті, як ви сказали, методи, як правило, занадто довгі. Але цікаво побачити цю криву! Дійсно, речі слід робити максимально простими, але не простішими.
Joonas Pulakaka

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

@ Роберт Харві: Другий приклад - це чудовий публічний метод, але викликати його всередині самого класу сумнівно, тому що ви не знаєте, що саме він робить, перш ніж подивитися, як це реалізовано. Наприклад, це може перевірити наявність нуля. Дивіться моє доповнення вище.
Joonas Pulakaka

@Joonas: Досить справедливо.
Роберт Харві

13

"Будьте ліберальні з коментарями"

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


1
самодокументування коду, безумовно, приємно. Хоча мені подобається мати коментарі поряд із чимось на зразок простих обчислень (щоб виразити, що таке тип повернення або повернуте значення). Однак якщо ваші коментарі потребують більше слів, ніж сам код, напевно, час переписати код.
сова

6
Я повинен погодитися з тим, як сова поставив цю. Чистий код є кращим, ніж коментарі.
riwalk

4
Ви все ще потребуєте "чому" там!

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

12

GoTo вважається шкідливим

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

Будь-яка «найкраща практика», яка не допускає розумних та задокументованих винятків із її правил, просто жахлива.


16
Я продовжую програмувати дев'ять років без жодної заяви goto (включаючи декілька державних машин, як ви згадували). Розширіть свій розум на нові ідеї.
riwalk

3
@Mathieu M. - погодився - змішування GOTO із структурованими операторами управління не є розумним. (Це був чистий C, і це не проблема.
MZB

1
@ Stargazer2 - за допомогою простого FSM це залежить від того, чи розміщення стану в змінній та використання його як індексу для виклику процедури (чи не те саме, що і обчислений GOTO?) Дає чіткіший / швидший код, ніж використання лічильника програм як стан ЧФМ. Я не виступаю за це як найкраще рішення за більшості обставин, просто найкраще рішення за деяких обставин. Розширіть свою думку до альтернативних підходів.
MZB

5
@MZB, ви не погодилися б, що виклик функції - це також просто обчислений GOTO? Те саме стосується та / while / if / else / переключає конструкції, серед інших. Мовні дизайнери відмовляються від прямої зміни програмного лічильника не просто так. Не використовуйте goto.
riwalk

3
Безпосередньо реалізація державного автомашини, мабуть, є антипатерном. Існує маса способів створити державну машину, не виражаючи станів і переходів буквально. наприклад,import re
SingleNegationElimination

12

Жертви, які ми робимо, щоб зробити код перевіряючим

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

  • Створення інтерфейсу для кожного класу. Це подвоює кількість класів (файлів) для обробки та дублює код. Так, програмування інтерфейсів добре, але саме для цього призначені державні / приватні специфікатори.
  • Кожен клас, який не призначається при запуску, потребує фабрики. Ясна річ, new MyClass()набагато простіше, ніж писати фабрику, але тепер метод, який її створює, не може бути перевірений ізольовано. Якби не цей факт, я б лише 1/20-я склав кількість заводських класів, які я зараз роблю.
  • Зробіть для кожного класу загальнодоступним, що перемагає мету взагалі мати специфікатори доступу для класів. Однак до непублічних класів не можна отримати доступ (і, таким чином, перевірити) з інших проектів, тому єдиним іншим варіантом є переміщення всього тестового коду до того ж проекту (і таким чином звільнення його разом із кінцевим продуктом).
  • Ін'єкційна залежність Очевидно, що давати кожному другому класу, я використовую поле і конструктор-параметр - це значно більше роботи, ніж просто їх створення, коли мені це потрібно; але тоді я вже не можу перевірити цей клас ізольовано.
  • Принцип єдиної відповідальності, який викликав у мене стільки головних болів, я переніс це на свою власну відповідь .

То що ми могли зробити, щоб виправити це? Нам потрібна кардинальна зміна мовної архітектури:

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

Коротше кажучи, нам потрібна мова, розроблена з нуля, маючи на увазі тестабельність .


Я здогадуюсь, що ти ніколи не чув про TypeMock ? Це дозволяє висміювати класи, приватні особи, статику (фабрику), будь-що.
Аллон Гуралнек

@Allon: У мене є, але це далеко не безкоштовно , що робить його не варіантом для більшості людей.
BlueRaja - Danny Pflughoeft

Якщо вам доведеться писати багато фабричних занять, то ви робите щось не так. Інтелектуальні бібліотеки DI (наприклад, Autofac для C #) можуть використовувати Func <T>, Lazy <T>, Delegates тощо для заводів, не записуючи жодного котла.
gix

10

Розділення додатків на рівні; Шар даних, бізнес-шар, шар інтерфейсу користувача

Основна причина, що мені це не подобається, полягає в тому, що більшість місць, які дотримуються цього методу, використовують дуже крихкі рамки для його виконання. IE UI Layer кодується вручну для роботи з об'єктами бізнес-рівня, об'єкти бізнес-рівня кодуються вручну для роботи з бізнес-правилами та базою даних, база даних - SQL і вже досить крихкою та керується групою "DBA", яка не любить зміни.

Чому це погано? Найпоширеніший запит на вдосконалення, ймовірно, "мені потрібне поле на екрані X з Y." Вибух! У вас просто є нова функція, яка впливає на кожен окремий шар, і якщо ви розділяєте шари з різними програмістами, це просто стало великою проблемою, що стосується декількох людей і груп, для дуже простої зміни.

Окрім того, я не знаю, скільки разів я був в аргументах, що йдуть приблизно так. "Поле імені обмежено максимальною довжиною 30, це рівень інтерфейсу користувача, бізнес-рівень або проблема з рівнем даних?" І є сто аргументів, і правильної відповіді немає. Відповідь однакова, вона впливає на всі шари, ви не хочете робити інтерфейс користувача тупим і проходити всі шари, а також не працювати з базою даних, так що користувач дізнається, що його запис занадто довгий. Якщо змінити, це вплине на всі шари тощо.

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

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

Мені, мабуть, за це вдаряться, але це є :)


+1, звучить як моє останнє місце роботи до найменшої деталі! Я принципово поважаю багаторівневі програми, проте занадто багато людей трактують це як срібну кулю, коли це не має сенсу. Більшість бізнес-програмних продуктів мають надзвичайно низьку кількість ділової логіки, і те, що вона має, є відносно простим. Це може зробити бізнес-логіку наплавлення кошмаром кодового коду. Багато разів рядки можуть бути розмитими між доступом до даних та бізнес-логікою, оскільки запит - це бізнес-логіка.
maple_shaft

... Крім того, більшість магазинів абсолютно не впізнають логіку інтерфейсу або логіку презентації. Оскільки вони не розуміють, наскільки мало ділової логіки існує в типовому додатку CRUD, їм здається, що вони повинні щось робити неправильно, коли більшість їх логіки знаходиться в шарі презентації як логіка презентації. Він помилково ідентифікується як бізнес-логіка, і тоді люди підштовхують його до сервера для ще одного дзвінка на сервер. Тонкий клієнт може і повинен мати логіку презентації, напр. (Сховати textField2, якщо в dropDown3 обрано параметр1).
maple_shaft


7

Історії користувачів / Користування справами / Особи

 

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


7

Обмеження 80 знаків / ліній німі

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

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

Звичайно, є редактори CLI, релігійно використовувані * nix динозаврами, які слідують усталеним обмеженням своїх терміналів VT220, але чому ми решта нас дотримуємось того ж стандарту?

Я кажу, прикрутіть межу 80 знаків. Якщо динозаврів достатньо епічних, щоб зламати emacs / vim цілий день, чому б не могли бути спроможні створити розширення, яке автоматично перегортає лінії або надає можливості горизонтальної прокрутки своїм IDE CLI?

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

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

Редагувати:

Зрозуміло, що багатьом дискам не подобається горизонтальна смуга прокрутки, тому що для цього потрібен жест миші, тому ... Чому б не збільшити межу ширини стовпців на більшу кількість (ніж 80) для тих, хто використовує сучасні дисплеї.

Коли монітори комп’ютерів 800х600 стали нормою для більшості користувачів, веб-розробники збільшували ширину своїх веб-сайтів, щоб пристосувати більшість ... Чому розробники не можуть зробити те саме.


1
@Orbling Nice GWB-логіка з ___ - це злий кут. Отже, ви ненавидите hScroll, чи є у вас поважна причина, чому ширина кола повинна бути обмежена до 80 знаків? Чому б не 160 чи 256? Я думаю, що всі ми можемо припустити, що більшість розробників вивели свої термінали VT220 і замінили їх на puTTY, щоб вони могли програматично розширити ширину.
Еван Плейс

4
Я вважаю за краще, щоб ми дотримувалися межі 80 char. Як тільки ви дасте мені більше горизонтального простору, я спробую відкрити додаткові документи поруч із рештою. Мені б не хотілося прокручувати чотири способи. Крім того, я часто помічав, що я змушений писати більш читабельний код із обмеженням 80 char.
Філіп Дупанович

2
як би ти це надрукував?

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

3
Відступ на 2 пробіли. І користуйтеся редактором з автоматичним відстеженням відступу. Я роблю це таким чином роками, нічого великого. (Тут допомагає Emacs з потрібними режимами.)
швидко_значення

5

Міряти, міряти, міряти

Так добре, відміряйте, але для виділення помилок продуктивності, вимірювання робіт, а також послідовного усунення. Ось метод, який я використовую.

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


5

Мій вчитель вимагає запустити всі свої ідентифікатори (не включаючи константи) з малих літер, наприклад myVariable.

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


9
У мене був викладач, який вимагав camelCase, тому що він наполягав на тому, що люди використовують у реальному світі ... В той же час я працював у двох різних групах під час своєї роботи - обидві групи наполягали на under_scores. Важливо, що ваша група використовує. Він міг би визначити себе провідним програмістом, і все було б добре в моїй книзі - ми дотримуємось його конвенцій, - але він завжди висловлював свою думку як "так, як це робиться в реальному світі", як ніби немає інших дійсних шлях.
xnine

@xnine У мене ще недостатньо представників на цьому сайті, щоб оцінити ваш коментар, тому я просто відповім на цей коментар схвалення.
Maxpm

5
Справа верблюда (перша літера) - це досить поширена умова, а також регістр Паскаля (перша буква кожного слова з великої літери). У більшості мов camelCase використовується на приватних / внутрішніх змінних, де PascalCase використовується у класах, методах, властивостях, просторах імен, публічних змінних. Це не погана практика звикнути просто бути готовим до проектів, які можуть використовувати іншу схему іменування.
Еван Плейс

2
Просто вигадка. Деякі мови випливають із значення того, перша буква змінної є великою чи ні. В одній такій мові, якщо перша літера є великою, змінна трактується як константа - будь-яка спроба її зміни призведе до помилки.
Берін Лорич

1
У програмі Go публічні методи та учасники занять починаються з великої літери; приватні з малої літери.
Джонатан Леффлер

5

Використовуйте одиночні

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


2
Це ціла купа негативів, яка залишила мене досить розгубленою щодо вашої фактичної позиції щодо одинаків.
Пол Різник

1
@Paul Butcher: Я ненавиджу синглів, і його ніколи не слід використовувати

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

6
Хто каже, що використання Singeltons - найкраща практика?
Філ Мандер

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

5

Використання неподписаного int в якості ітератора

Коли вони дізнаються, що використання підписаного int набагато безпечніше і менш схильне до помилок. Чому так важливо, щоб індекс масиву міг бути лише позитивним числом, щоб усі раді занедбати той факт, що 4 - 5 - це 4294967295?


Гаразд, зараз мені цікаво - чому ти це кажеш? Я почуваюся трохи німим - чи можете ви навести кілька прикладів коду, щоб створити резервну копію своїх заяв?
Пол Натан

4
@Paul Nathan: що стосується баггісті, ось один приклад: for (unsigned int i = 0; i <10; i ++) {int crash_here = my_array [max (i-1,0)];}
AareP

@AareP: Безумовно - я припускаю, що ви посилаєтесь на те, що коли неподписаний int 0зменшується на 1, ви насправді отримуєте максимальне позитивне значення, яке може зберігати неподписаний int?
Адам Пейнтер

1
@Adam Paynter: так. Це може здатися нормальним для програмістів c ++, але давайте поглянемо на те, що "непідписаний int" - це одна погана "реалізація" лише позитивних чисел.
AareP

Недобра ідея для невеликих вбудованих машин - часто неподписані вкладиші створюють менший, швидший код. Залежить від компілятора та процесора.
quick_now

4

Методи не повинні бути довше одного екрана

Я повністю погоджуюся з принципом єдиної відповідальності, але чому люди сприймають це як «функція / метод може мати не більше однієї відповідальності на найтоншому рівні логічної деталізації»?

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

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

Ось моє правило ...

Напишіть функції / методи для досягнення чогось

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

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

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

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

Обмежте зайві абстракції і не забруднюйте автозаповнення.


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

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

1
@Jeremy Як? Яким чином абстрагування розділу коду та розміщення його у своєму власному методі робить його більш читабельним, ніж просто розміщення коментаря в одному рядку у верхній частині цього коду, що описує, що він робить? Якщо припустити, що блок коду використовується лише один раз у цьому розділі коду. Є чи це на самому справі , що важко для більшості програмістів , щоб розкласти робочі частини коду , поки вони читають його і / або розмістити кілька однорядковий коментар , щоб нагадати їм , що він робить , якщо вони не можуть?
Еван Плейс

4
@Evan: Ефективне введення фрагментів коду у функції дає їм ім'я , сподіваємось, добре пояснює, що робить цей фрагмент коду. Тепер, де б не називався цей фрагмент коду, ви можете побачити ім'я, що пояснює, що робить код , замість того, щоб аналізувати та розуміти сам алгоритм. Якщо все зроблено добре, це може надзвичайно полегшити читання та розуміння коду.
sbi

1
+1, і я би дав більше, якби міг. Нічого немає нічого поганого з грудкою коду С, що містить 1000 рядків в одній функції (наприклад, аналізатор з масивним перемикачем ()) ЗАБЕЗПЕЧЕНО, що намір зрозумілий і простий. Виривання всіх дрібних шматочків та виклик їх просто ускладнює розуміння речі. Звичайно, для цього теж є межі .... розумне судження - це все.
quick_now
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.