Фон
Я працюю над поточним проектом 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()
є вже складним. З часом воно стане складнішим.
Чи я це роблю правильно?