Чи довгі методи завжди погані? [зачинено]


64

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

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

Наприклад, у мене є кілька видів Django, які трохи обробляють об'єкти, перш ніж надсилати їх у подання, довгий метод - 350 рядків коду. У мене написаний код так, що він стосується параметрів - сортування / фільтрація набору запитів, потім побіжно виконується деяка обробка об’єктів, на які повернувся мій запит.

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

variable_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

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

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

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

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

То чи існує випадок, коли довгі методи не завжди погані? Чи завжди є такі способи написання, коли вони будуть використовуватися лише в одному місці?

ОНОВЛЕННЯ: Схоже, я задав це питання більше року тому.

Тому я відновив код після (змішаної) відповіді тут, розділив його на методи. Це додаток Django, який витягує з бази даних складні набори пов'язаних об'єктів, тому аргумент тестування вийшов (можливо, знадобилося б більша частина року для створення відповідних об'єктів для тестових випадків. У мене є тип "це потрібно зробити вчора") робоче середовище, перш ніж хтось скаржиться). Виправити помилки в тій частині коду зараз незначно простіше, але це не так масово.

перед:

#comment 1 
bit of (uncomplicated) code 1a  
bit of code 2a

#comment 2 
bit of code 2a
bit of code 2b
bit of code 2c

#comment 3
bit of code 3

зараз:

method_call_1
method_call_2
method_call_3

def method_1 
    bit of (uncomplicated) code 1a  
    bit of code 2a

def method_2 
    bit of code 2a
    bit of code 2b
    bit of code 2c

def method_3
    bit of code 3

156
Усі абсолюти погані. Завжди.
Йоахім Зауер

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

4
@gnat: вау, чи не було б якесь ручне вбудовування (за допомогою препроцесора) на етапі збирання кращим рішенням тут?
Йоахім Зауер

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

2
Довгі методи не завжди погані; але вони - це те, на що слід завжди дивитися і запитати себе "це погано?"
Carson63000

Відповіді:


80

Ні, довгі методи не завжди погані.

У книзі « Кодекс завершений» відміряється, що довгі методи інколи швидше і простіше писати, і не призводять до проблем з обслуговуванням.

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

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

РЕДАКТИРУЙТЕ: Коли коментарі зроблені, я додаю цікавий момент до відповіді. Я б також перевірив показники складності для функції (NPATH, цикломатична складність або навіть краща CRAP).

Насправді, я рекомендую не перевіряти такі показники на довгих функціях, а включати попередження про них за допомогою автоматизованих інструментів (наприклад, контрольного стилю для Java) НА ВСІМ ФУНКЦІЇ.


41
+1: "Ні, довгі методи не завжди погані", але вони майже завжди погані
Бінарний Вор'єр

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

6
+1, але я все ж рекомендую перевірити циклічну складність довгого методу. Високі значення вказують на методи, які фактично неможливо одинично перевірити (а довгі методи дуже рідко позбавлені логіки потоку управління).
Даніель Б

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

4
@ da_b0uncer Це також політика, яку я дотримуюся. Читати код важче, ніж писати, тому додаткові зусилля при написанні, щоб зробити код більш читабельним, окупаються.
deadalnix

55

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

Читання: Я не впевнений у інших, але я не можу швидко прочитати 350 рядків коду. Так, якщо це мій власний код, і я можу зробити багато припущень щодо нього, я міг би проглянути його дуже швидко, але це, окрім суті. Поміркуйте, наскільки простіше було б прочитати цей метод, якби він складався з 10 викликів до інших методів (кожен із описовою назвою). Роблячи це, ви внесли шари в код, і метод високого рівня дає короткий, солодкий контур читачеві щодо того, що відбувається.

Редагувати - щоб сказати про це в іншому світлі, подумайте про це так: як би ви пояснили цей метод новому члену команди? Звичайно, вона має деяку структуру, яку ви можете підсумувати за рядками "добре, це починається з виконання A, потім B, потім іноді C і т.д." Наявність короткого методу "огляду" виклику інших методів робить цю структуру очевидною. Вкрай рідко можна зустріти 350 рядків коду, які не приносять користі; людський мозок не призначений для того, щоб мати справу зі списками 100-ти предметів, ми групуємо їх.

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

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

Рефакторинг та структура: Довгі методи часто є ознаками того, що деякої структури бракує коду. Часто розробник не міг розібратися, що спільного між різними частинами цього методу, і де між ними може бути проведена лінія. Усвідомлення того, що довгий метод є проблемою, і намагання розділити його на більш дрібні методи - це перший крок на більш тривалому шляху до фактичного визначення кращої структури для всієї справи. Можливо, вам потрібно створити клас чи два; це не обов’язково буде складніше в підсумку!

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


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

2
Добре дивлячись на список, наведений вище: читабельність, яку я б сказала, колишній досвід збільшується тим, що метод довший, містить багато коментарів, і добре відформатований, а не потрібно переходити з коду від методу до методів, хоча це, мабуть, досить суб'єктивно. Я не очікую повторного використання частин коду. Більшість повторного використання коду досягається від успадкування на даний момент.
wobbily_col

1
@wobbily_col BTW, якщо ви шукаєте добре написаний текст, який проходить через обґрунтування коротших методів, прочитайте перші кілька глав Чистого кодексу , що досить добре справляється з поясненнями.
Даніель Б

5
@wobbily_col Ви кажете, що занадто багато стрибати, щоб зрозуміти код багатьма методами, є заплутаним, я думаю, що тут відсутність важливості іменування. Якщо метод названий добре, вам не потрібно дивитись на нього, щоб дізнатися, що він робить, метод виклику повинен бути повністю зрозумілим без будь-яких базових знань про те, якими методами він викликає, наприклад, коли-небудь ви використовували someVar.toString()та відчували вам потрібно було переглянути код toString, щоб знати, що він робить? Ви просто читали прямо повз це через хороший метод іменування.
Джиммі Хоффа

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

28

Довгі методи завжди погані, але іноді кращі за альтернативи.


5
без пояснення ця відповідь може стати марною у випадку, якщо хтось інший висловить протилежну думку. Наприклад, якщо хтось розміщує претензію на кшталт "Довгі методи ніколи не є поганими, але іноді гірші за альтернативи". , як ця відповідь допоможе читачеві вибрати дві протилежні думки? Розглянемо редагування ІНГ його в кращій формі
комар

9

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

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


7

Довгі методи не завжди погані. Зазвичай вони є ознакою того, що може виникнути проблема.

У системі, над якою я працюю, у нас є півдесятка або близько того методів, довжиною яких більше 10 000 рядків. Наразі одна довжина 54 830 рядків. І це нормально.

Ці смішно довгі функції дуже прості та автогенеровані. Цей великий монстр довжиною 54 830 містить дані про щоденні полярні рухи з 1 січня 1962 року по 10 січня 2012 року (наш останній реліз). Ми також випускаємо процедуру, за допомогою якої наші користувачі можуть оновлювати цей автоматично створений файл. Цей вихідний файл містить дані полярного руху з http://data.iers.org/products/214/14443/orig/eopc04_08_IAU2000.62-now , автоматично перекладені на C ++.

Читання того, що веб-сайт на льоту не можливий при безпечній установці. Немає зв’язку із зовнішнім світом. Завантаження веб-сайту як локальної копії та розбору в C ++ також не є можливим; розбір йде повільно , і це має бути швидким. Завантаження, автоматичний переклад на C ++ та компіляція: тепер у вас є щось, що швидко. (Просто не компілюйте його оптимізовано. Дивно, скільки часу оптимізуючий компілятор забирає 50 000 рядків надзвичайно простого прямого коду. На моєму комп’ютері потрібно півгодини, щоб скомпілювати цей файл, оптимізований. А оптимізація не робить абсолютно нічого . Немає чого оптимізувати. Це простий код прямого рядка, одне твердження про присвоєння.


6
"одне повідомлення про призначення" за іншим "... Я б назвав це" файлом даних ". Чому це код?
Йоахім Зауер

3
@JoachimSauer - Оскільки аналіз великого файлу даних під час роботи в програмі Монте-Карло - погана ідея. Дуже-дуже погана ідея.
Девід Хаммен

4
@DavidHammen: тоді робіть це під час ініціалізації, як і ви змушуєте це робити ваш лінкер / завантажувач. Або запишіть файл даних як структуру С у файл заголовка, а не код C. Принаймні тоді завантажувач завантажиться як блок даних.
Хав'єр

3
@Javier: Навіть під час ініціалізації це може бути дуже поганою ідеєю, принаймні, в Монте-Карло. Моделювання, яке займає кілька хвилин, щоб ініціалізуватися, але лише кілька секунд для запуску йде проти зерна отримання десятків тисяч пробіжок за ніч. Зміна ключових завдань ініціалізації для складання завдань часу вирішує цю проблему. Ми спробували ряд методів, включаючи підхід до складеної структури даних. Це просто не працює, або в деяких випадках було б дуже важко змусити його працювати (наприклад, величезна гравітаційна модель). Підхід до прямого коду легко автогенерувати, легко перевірити. Це просто некрасивий код.
Девід Хаммен

7
+1 цікава історія. згенерований код насправді не є вихідним кодом, звичайно, тому можна стверджувати, що це не «порушує» правило. можна припустити, що сам генератор коду мав непогані короткі методи
jk.

7

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

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

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


1
"Немає нічого поганого в плануванні від початку до рефактора перед тим, як перевірити його." +1 для цього. На сьогоднішній день більшість ІДЕ мають інструменти рефакторингу, які також роблять це надзвичайно просто. Але є зворотний метод, коли ви делегуєте речі неіснуючим функціям, а пізніше перейдіть і заповніть методи, але я ніколи не міг так зашифрувати, як я намагався.
Тярт

+1 за "Необхідність" [тримати] найкоротший метод у голові "- знак того, що ти не порушуєш його найоптимальнішим чином",
Майкл Шоу

4

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


34
Завжди беруть участь щонайменше два програмісти: "ти" та "ти, три тижні відтепер".
Йоахім Зауер

3

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

Саме ваш метод повинен бути орієнтований лише на завдання perforimng 1.

А якщо потрібно зателефонувати іншим методом до дому, то зробіть це в іншому випадку, продовжуйте працювати з тим, про який ви вже пишете. Також для зручності в читанні можна додавати коментарі. Зазвичай програмісти використовують багаторядкові коментарі (/ ** / в C, C ++, C # і Java) для описів методів і використовують однорядкові коментарі (// в C, C ++, C # і Java). Також доступні хороші інструменти для документації для більшої читабельності коду (наприклад, JavaDoc ). Ви також можете переглянути коментарі на основі XML, якщо ви розробник .Net.

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


Також відомий як "Функція повинна робити ОДНЕ."
lorddev

3

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

У Code Complete 2 є відмінна коротка дискусія про довжину процедур.

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

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

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


2

Ще один голос, що це майже завжди неправильно. Я знаходжу два основних випадки, коли це правильна відповідь:

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

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

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


1
Процес 50 кроків, ймовірно, може бути зведений до декількох відро. Крок 1 - 9 - це перевірка параметрів, тому створіть новий метод, який називається перевірка параметрів. (Я впевнений, що є кілька прикладів, коли це неможливо. Мені було б цікаво побачити його).
шістдесят футів

@sixtyfootersdude: Безумовно, ви могли це зламати. Я не сказав, що це неможливо, я сказав, що нічого не можна отримати, розірвавши це. Хоча це не було 50 кроків, я вдарив щось подібне: Створення ігрового світу. №1 створив порожній світ, №2 створив місцевість, а потім цілу купу кроків після цього так чи інакше масажував його.
Лорен Печтел

& sixtyfootersdude: Дивно, як ви знаєте код, якого ви ніколи не бачили, і як його вдосконалити.
gnasher729

2

Я хотів звернутися до прикладу, який ви подали:

Наприклад, у мене є кілька видів Django, які трохи обробляють об'єкти, перш ніж надсилати їх у подання, довгий метод - 350 рядків коду. У мене написаний код, щоб він мав справу з параметрами - сортування / фільтрування набору запитів, потім поступово виконується деяка обробка об'єктів, на які повернувся мій запит.

В моїй компанії наш найбільший проект побудований на Django, і ми також давно переглядаємо функції (багато - це більше 350 рядків). Я б зауважив, що наші не повинні бути такими довгими, і вони шкодять нам.

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

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


2

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

function nextSlide() {
  var content = getNextSlideContent();
  hideCurrentSlide();
  var newSlide = createSlide(content);
  setNextSlide(newSlide);
  showNextSlide();
}

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

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

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

   if (hasMoreRecords()) { ... }

це, безумовно, читабельніше, ніж

if (file.isOpen() && i < recordLimit && currentRecord != null) { ... } 

Правильно?

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


1

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

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


0

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

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


Допоможіть зменшити Код , що ?
Авнер Шахар-Каштан

@ AvnerShahar-Kashtan, він, мабуть, означає "дублювання" :-)
Péter Török

0

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

Я маю на увазі, що фактичний акт рефакторингу вашого зразка від:

varaible_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

до

Status status = new Status();
status.variable1 = 0;
status.variable2 = 0;
for object in queryset :
     if object.condition_condition_a and status.variable2 > 0 :
     status.variable1 += 1
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

а потім до

class Status {
    variable1 = 0;
    variable2 = 0;

    void update(object) {
        if object.condition_condition_a and variable2 > 0 {
            variable1 += 1
        }
    }
};

Status status = new Status();
for object in queryset :
     status.update(object);
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

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


0

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

foreach(var x in y)
{
    //do ALL the things
    //....
}

і тіло циклу не є надзвичайно локалізованим (тобто ви можете надіслати його менше 4-х параметрів), то, ймовірно, краще перетворити його на:

foreach(var x in y)
{
    DoAllTheThings(x);
}
...
void DoAllTheThings(object x)
{
    //do ALL the things
    //....
}

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

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


0

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

По-друге, що стосується функцій / процедур:

void setDataValueAndCheckForRange(Data *data) {/*code*/} 

є хорошим методом, якщо він перевіряє на діапазон лише "Дані". Це метод BAD, коли той самий діапазон застосовується для декількох функцій (приклад неправильного коду):

void setDataValueAndCheckForRange(Data *data){ /*code */}
void addDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void subDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void mulDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}

Це необхідно змінити на:

bool isWithinRange(Data *d){ /*code*/ }
void setDataValue(Data *d) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void addDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void subDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void mulDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 

ПОВЕРНЕННЯ коду, наскільки це можливо. І це можливо, коли кожна функція вашої програми досить ПРОСТА (не обов'язково проста).

ЦІТА: ГРАМА складається з крихітних зерен. Океан складається з крихітних крапель води .. (- Сівананда)


0

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

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

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


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