Contexte
Je travaille sur un projet C # en cours. Je ne suis pas un programmeur C #, principalement un programmeur C ++. On m'a donc confié des tâches fondamentalement faciles et de refactorisation.
Le code est un gâchis. C'est un énorme projet. Comme notre client exigeait des versions fréquentes avec de nouvelles fonctionnalités et des corrections de bogues, tous les autres développeurs ont été forcés d'adopter une approche par force brute lors du codage. Le code est hautement impossible à maintenir et tous les autres développeurs sont d'accord avec lui.
Je ne suis pas ici pour débattre de savoir s'ils l'ont bien fait. En refactorisant, je me demande si je le fais de la bonne façon car mon code refactoré semble complexe! Voici ma tâche comme exemple simple.
Problème
Il y a six classes: A
, B
, C
, D
, E
et F
. Toutes les classes ont une fonction ExecJob()
. Les six implémentations sont très similaires. Fondamentalement, au début a A::ExecJob()
été écrit. Ensuite, une version légèrement différente a été requise qui a été implémentée dans B::ExecJob()
par copier-coller-modification de A::ExecJob()
. Lorsqu'une autre version légèrement différente a été requise, a C::ExecJob()
été écrite et ainsi de suite. Les six implémentations ont du code commun, puis des lignes de code différentes, puis à nouveau du code commun et ainsi de suite. Voici un exemple simple des implémentations:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Où SN
est un groupe d'exactement les mêmes déclarations.
Pour les rendre communs, j'ai créé une autre classe et déplacé le code commun dans une fonction. Utilisation de paramètres pour contrôler le groupe d'instructions à exécuter:
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);
}
Notez que cet exemple n'utilise que trois classes et des instructions simplifiées. En pratique, la CommonTask()
fonction semble très complexe avec toutes ces vérifications de paramètres et il y a beaucoup plus d'instructions. En outre, dans le code réel, il existe plusieurs CommonTask()
fonctions qui ressemblent à.
Bien que toutes les implémentations partagent un code commun et que les ExecJob()
fonctions semblent plus mignonnes, il existe deux problèmes qui me dérangent:
- Pour tout changement
CommonTask()
, les six (et peut-être plus à l'avenir) fonctionnalités doivent être testées. CommonTask()
est déjà complexe. Cela deviendra plus complexe au fil du temps.
Est-ce que je le fais de la bonne manière?