2009-07-08 2 views
0

Manchmal haben Sie nur eine Liste von Operationen, die in einer festgelegten Reihenfolge ausgeführt werden müssen, wie bei der Implementierung eines Sequenzdiagramms. Was sind die besten Möglichkeiten, um die Code-Ausführungsreihenfolge zu erzwingen, um Refactoring zu verhindern, das durch Sequenzwechsel subtile Bugs einführt?Erzwingen Code-Ausführungssequenz

Angenommen, vorhandene Komponententests würden keine Probleme verursachen, die durch die Änderung der Reihenfolge der Ausführung von foo() und bar() im Folgenden verursacht werden.

Einige der Methoden, die ich je gesehen habe und verwendet:

  1. Kommentare (verlässt sich auf die Menschen zu lesen & sie zu verstehen):

    // do this
    foo();
    // then this
    bar();

  2. Fließend Grammatik (um den Code mehr wie Englisch zu lesen und mutwilliges Refactoring zu vermeiden):

    obj
    .Do
    .foo()
    .Then
    .bar();

  3. Zustandsvariablen & balking (zu erarbeiten):

    foo_done=false;
    if(foo()) foo_done=true;
    if(foo_done) bar(); else throw_an_exception;

  4. Gruppierung logische Blöcke in Funktionen:

    void foo_bar()
    {
    foo();
    bar();
    }

... und viele mehr zu hässlich zu beschreiben (Verschachtelung, Veranstaltungen, Anordnungen von Funktionszeigern, Namensgebung Funktionen Begin(), Mitte() und End() ...) .

Gibt es irgendwelche besser konstruierten Muster für diese Art von Sache?

+1

Ich denke, ein konkreteres Beispiel könnte bessere Antworten hervorbringen. Wie streng ist die Reihenfolge, in der Dinge erledigt werden müssen? Wenn Sie immer einige Methoden in einer genauen Reihenfolge aufrufen müssen, ist dies ein Fehler, der mit einer void doEverything() falsch ist, die alle in der richtigen Reihenfolge aufruft. Wenn Sie Vorgänge in Ad-hoc-Aufträgen aufrufen müssen, welche Einschränkungen gibt es? Warum müssen sie in einer bestimmten Reihenfolge aufgerufen werden? operieren sie in einem gemeinsamen Staat?Haben sie Nebenwirkungen, die Sie nicht testen? –

Antwort

1

Ich bin verwirrt, warum die Reihenfolge signifikant ist, wenn Komponententests sie nicht abfangen würden, und die Abhängigkeiten nicht explizit im Code sind; es bedeutet, dass Nebenwirkungen ein entscheidender Teil der Operation von foo() und bar() sind. In diesem Fall wäre die beste Designstrategie, diese Nebenwirkungen explizit zu machen!

+0

Wie also machen Sie die Abhängigkeiten explizit? Ist die einzige Möglichkeit, um die Durchführung eines Tests außerhalb des Code-Körpers sicherzustellen, oder gibt es Möglichkeiten, die Sequenz explizit zu machen? – lotsoffreetime

+0

Eh? Ich meine im wahrsten Sinne des Wortes: Datei handle = function_a (Dateiname); Anzahl der Datensätze = function_b (Dateihandle); Datenstruktur = function_c (Dateihandle, Anzahl der Datensätze); Niemand wird die Reihenfolge dieser ändern ... –

+0

Nicht alle Sequenzen sind so offensichtlich. Was ist mit get_price()? apply_discount (10%); add_tax(); Wenn der Rabatt angewendet wird, nachdem die Steuer hinzugefügt wurde, würde es Probleme geben und nur Ihr Komponententest (und das Verständnis der Geschäftslogik) wird Sie retten. Vielleicht ist "Sequenzierung von Geschäftslogik" die Formulierung, nach der ich suche. – lotsoffreetime

0

Sie schreiben Komponententests, um zu überprüfen, was passiert ist (Zustand, Attribute ändern sich), nachdem Sie eine Prozedur aufgerufen haben. Daher müssen Sie nicht prüfen, ob eine Methode aufgerufen wurde oder nicht.

Auch, wenn Sie Ihren Test an eine Methode binden, später, wenn Sie Ihr System ändern, um eine andere Methode mit den gleichen Auswirkungen von foo() zu verwenden, wird Ihr Test fehlschlagen, auch wenn Ihr System die richtigen Dinge tut.