fundo
Estou trabalhando em um projeto C # em andamento. Eu não sou um programador de C #, principalmente um programador de C ++. Então, fui designado basicamente para tarefas fáceis e de refatoração.
O código está uma bagunça. É um projeto enorme. Como nosso cliente exigia lançamentos frequentes com novos recursos e correções de erros, todos os outros desenvolvedores foram forçados a adotar uma abordagem de força bruta durante a codificação. O código é altamente insustentável e todos os outros desenvolvedores concordam com ele.
Não estou aqui para debater se eles fizeram certo. Como estou refatorando, estou me perguntando se estou fazendo isso da maneira certa, pois meu código refatorado parece complexo! Aqui está minha tarefa como exemplo simples.
Problema
Há seis classes: A
, B
, C
, D
, E
e F
. Todas as classes têm uma função ExecJob()
. Todas as seis implementações são muito semelhantes. Basicamente, a princípio A::ExecJob()
foi escrito. Em seguida, foi necessária uma versão ligeiramente diferente, que foi implementada na B::ExecJob()
modificação de copiar e colar de A::ExecJob()
. Quando outra versão ligeiramente diferente foi necessária, C::ExecJob()
foi escrita e assim por diante. Todas as seis implementações têm algum código comum, depois algumas linhas de código diferentes, novamente algum código comum e assim por diante. Aqui está um exemplo simples das implementações:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Onde SN
está um grupo exato das mesmas instruções.
Para torná-los comuns, criei outra classe e movi o código comum em uma função. Usando o parâmetro para controlar qual grupo de instruções deve ser executado:
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);
}
Observe que, este exemplo emprega apenas três classes e instruções simplificadas demais. Na prática, a CommonTask()
função parece muito complexa com todas essas verificações de parâmetros e há muito mais instruções. Além disso, no código real, existem várias CommonTask()
funções de aparência.
Embora todas as implementações estejam compartilhando código comum e as ExecJob()
funções pareçam mais bonitas, existem dois problemas que estão me incomodando:
- Para qualquer alteração
CommonTask()
, todos os seis recursos (e podem ser mais no futuro) são necessários para serem testados. CommonTask()
já é complexo. Isso ficará mais complexo com o tempo.
Estou fazendo isso da maneira certa?