Hintergrund
Ich arbeite an einem laufenden C # -Projekt. Ich bin kein C # -Programmierer, hauptsächlich ein C ++ - Programmierer. Mir wurden also grundsätzlich einfache und umgestaltende Aufgaben übertragen.
Der Code ist ein Durcheinander. Es ist ein riesiges Projekt. Da unser Kunde häufige Releases mit neuen Funktionen und Fehlerkorrekturen forderte, waren alle anderen Entwickler gezwungen, beim Codieren Brute-Force-Ansätze zu wählen. Der Code ist kaum zu pflegen und alle anderen Entwickler stimmen dem zu.
Ich bin nicht hier, um zu diskutieren, ob sie es richtig gemacht haben. Während ich überarbeite, frage ich mich, ob ich es richtig mache, da mein überarbeiteter Code komplex erscheint! Hier ist meine Aufgabe als einfaches Beispiel.
Problem
Es gibt sechs Klassen: A
, B
, C
, D
, E
und F
. Alle Klassen haben eine Funktion ExecJob()
. Alle sechs Implementierungen sind sehr ähnlich. Grundsätzlich wurde zunächst A::ExecJob()
geschrieben. Dann wurde eine etwas andere Version benötigt, die B::ExecJob()
durch Copy-Paste-Modifikation von implementiert wurde A::ExecJob()
. Wenn eine andere etwas andere Version benötigt wurde, C::ExecJob()
wurde geschrieben und so weiter. Alle sechs Implementierungen haben einen gemeinsamen Code, dann verschiedene Codezeilen, dann wieder einen gemeinsamen Code und so weiter. Hier ist ein einfaches Beispiel für die Implementierungen:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Wo SN
ist eine Gruppe von genau gleichen Aussagen.
Um sie gemeinsam zu nutzen, habe ich eine weitere Klasse erstellt und den gemeinsamen Code in eine Funktion verschoben. Mit dem Parameter steuern Sie, welche Anweisungsgruppe ausgeführt werden soll:
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);
}
Beachten Sie, dass in diesem Beispiel nur drei Klassen und stark vereinfachte Anweisungen verwendet werden. In der Praxis CommonTask()
sieht die Funktion bei all diesen Parameterprüfungen sehr komplex aus, und es gibt viel mehr Anweisungen. In echtem Code gibt es auch mehrere CommonTask()
Funktionen , die aussehen.
Obwohl alle Implementierungen gemeinsamen Code verwenden und die ExecJob()
Funktionen besser aussehen, gibt es zwei Probleme, die mich stören:
- Bei jeder Änderung
CommonTask()
müssen alle sechs (und möglicherweise in Zukunft noch weitere) Funktionen getestet werden. CommonTask()
ist schon komplex. Mit der Zeit wird es komplexer.
Mache ich es richtig?