Повторення коду проти багатовідповідального методу


11

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

DoAction1();
DoAction2();

if (value)
    DoAction3();

DoAction4();

Який найкращий спосіб витягти такий код у метод і як його назвати?


1
Чому вони стійкі до вилучення в інший змістовний метод?
Чандраншу

Усі дії роблять щось незв'язане. Я б написати: void MethodThatDoAction1ThenAction2AndAction3IfValueAndThenAction4(). Я волів би бачити більше сенсу в: CodeBlock1().
yBee

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

1
Якщо це будь-яке втіху, переможець весни для довгих імен класу - AbstractInterruptibleBatchPreparedStatementSetterце лише на 0,4 менше, ніж ваш метод.
Чандраншу

1
@Chandranshu Я вважаю, що ваш коментар буде добре працювати як відповідь на це питання.
Саймон Форсберг

Відповіді:


13

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

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


11

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

Тепер, якщо ваш повторюваний код є результатом однієї роботи, і ці методи не використовуються іншими методами, вони просто метод Helpers, і тоді отриманий метод можна назвати як doXXXабо makeXXX... Я думаю, ви зрозуміли, що ви зрозуміли.

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

введіть тут опис зображення

З люб'язності: PicChef Facebook Page Photo


2

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

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

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

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

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

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

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

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

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


Мені подобається частина, яка витягує суть повторення коду: зменшити кількість коду, який потрібно перевірити, коли є зміна логіки
yBee

1

Якщо ви справді дотримуєтесь принципу єдиної відповідальності, то цей блок коду повинен мати певну мету, правда? Інакше ці методи були б в окремих класах.

Отже, яка мета цього блоку коду? Визначте це, і ви повинні мати змогу придумати ім’я.

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


1

У мене виникла ситуація, яка може бути схожа на вашу:

Існує клас, який визначає функціональність об'єкта, який він представляє:

class Functionality
{
protected:
void functionA();
void functionB();
...
void functionZ();
}

Потім є клас, який визначає робочі процеси для операцій високого рівня, які виконує об'єкт:

class Workflows: private Functionality
{
    void WorkflowA()
    {
        functionA();

        if (m_bValue) {
            functionB();
        }

        functionC();
    }
    ...
    void WorkflowB();
}

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

Відмова: Назви класів, які використовуються в цьому прикладі, є абсолютно неточними, але назви методів дають підказку. Рекомендується розсуд.

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