Фон
Я працюю над поточним проектом C #. Я не програміст на C #, передусім програміст на C ++. Тож мені було призначено в основному легкі та рефакторинг завдання.
Код - безлад. Це величезний проект. Оскільки наш клієнт вимагав частого випуску з новими функціями та виправленнями помилок, усі інші розробники були змушені застосовувати грубу силу під час кодування. Код дуже незрозумілий, і всі інші розробники погоджуються з ним.
Я не для того, щоб обговорювати, чи правильно вони це зробили. Коли я рефакторинг, мені цікаво, чи роблю це правильно, оскільки мій код, що ремонтується, здається складним! Ось моє завдання як простий приклад.
Проблема
Є шість класів: A, B, C, D, Eі F. Усі класи мають функцію ExecJob(). Усі шість реалізацій дуже схожі. В основному, спочатку A::ExecJob()було написано. Потім була потрібна дещо інша версія, яка була реалізована в B::ExecJob()модифікації copy-paste A::ExecJob(). Коли потрібна C::ExecJob()була інша трохи інша версія, писалася тощо. Всі шість реалізацій мають якийсь загальний код, потім кілька різних рядків коду, потім знову якийсь загальний код тощо. Ось простий приклад реалізації:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Де SNгрупа точно таких же тверджень.
Щоб зробити їх загальними, я створив інший клас і перемістив загальний код у функції. Використовуючи параметр для управління, яку групу операторів слід виконати:
Base::CommonTask(param)
{
S1;
if (param.s2) S2;
S3;
S4;
if (param.s5) S5;
}
A::ExecJob() // A inherits Base
{
param.s2 = true;
param.s5 = true;
CommonTask(param);
}
B::ExecJob() // B inherits Base
{
param.s2 = false;
param.s5 = true;
CommonTask(param);
}
C::ExecJob() // C inherits Base
{
param.s2 = false;
param.s5 = false;
CommonTask(param);
}
Зауважте, що в цьому прикладі використовуються лише три класи та спрощені заяви. На практиці ця CommonTask()функція виглядає дуже складною з усіма цими параметрами, які перевіряють параметри, і існує ще багато тверджень. Також у реальному коді є кілька CommonTask()функцій перегляду.
Незважаючи на те, що всі реалізації мають спільний код і ExecJob()функції виглядають кудись, є дві проблеми, які мене турбують:
- Для будь-якої зміни
CommonTask()потрібно перевірити всі шість (а може бути і більше в майбутньому) функцій. CommonTask()є вже складним. З часом воно стане складнішим.
Чи я це роблю правильно?