Antecedentes
Estoy trabajando en un proyecto en curso de C #. No soy un programador de C #, principalmente un programador de C ++. Así que me asignaron tareas básicamente fáciles y de refactorización.
El código es un desastre. Es un gran proyecto. Como nuestro cliente exigía lanzamientos frecuentes con nuevas características y correcciones de errores, todos los demás desarrolladores se vieron obligados a adoptar un enfoque de fuerza bruta mientras codificaban. El código es muy difícil de mantener y todos los demás desarrolladores están de acuerdo con él.
No estoy aquí para debatir si lo hicieron bien. Como estoy refactorizando, me pregunto si lo estoy haciendo de la manera correcta ya que mi código refactorizado parece complejo. Aquí está mi tarea como simple ejemplo.
Problema
Hay seis clases: A
, B
, C
, D
, E
y F
. Todas las clases tienen una función ExecJob()
. Las seis implementaciones son muy similares. Básicamente, al principio A::ExecJob()
fue escrito. Luego se requirió una versión ligeramente diferente que se implementó B::ExecJob()
mediante la copia-pegado-modificación de A::ExecJob()
. Cuando se requería otra versión ligeramente diferente, C::ExecJob()
se escribía, etc. Las seis implementaciones tienen un código común, luego algunas líneas de código diferentes, luego nuevamente un código común y así sucesivamente. Aquí hay un ejemplo simple de las implementaciones:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Donde SN
es un grupo de exactamente las mismas declaraciones.
Para hacerlos comunes, creé otra clase y moví el código común en una función. Usando el parámetro para controlar qué grupo de declaraciones se deben ejecutar:
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);
}
Tenga en cuenta que este ejemplo solo emplea tres clases y declaraciones demasiado simplificadas. En la práctica, la CommonTask()
función se ve muy compleja con todas esas comprobaciones de parámetros y hay muchas más declaraciones. Además, en código real, hay varias CommonTask()
funciones de búsqueda.
Aunque todas las implementaciones comparten código común y las ExecJob()
funciones se ven más lindas, existen dos problemas que me molestan:
- Para cualquier cambio
CommonTask()
, se necesitan las seis características (y pueden ser más en el futuro) para ser probadas. CommonTask()
Ya es complejo. Se volverá más complejo con el tiempo.
¿Lo estoy haciendo de la manera correcta?