2009-07-08 3 views
0

Parfois, vous n'avez qu'une liste d'opérations qui doivent être exécutées dans un ordre déterminé, comme lors de l'implémentation d'un diagramme de séquence. Quelles sont les meilleures façons d'appliquer l'ordre d'exécution du code, pour empêcher le refactoring d'introduire des bugs subtils à travers un changement de séquence?Application de la séquence d'exécution de code

Supposons que les tests unitaires existants n'attrapent aucun problème causé par le changement de l'ordre d'exécution de foo() et bar() dans ce qui suit.

Quelques-unes des méthodes que je l'ai vu et utilisé:

  1. Commentaires (associant des personnes de lecture & leur compréhension):

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

  2. grammaire Courant (pour que le code soit plus proche de l'anglais et décourage le refactoring gratuit):

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

  3. variables d'état & rechignant (préciser aussi):

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

  4. Regroupement des blocs logiques en fonctions:

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

... et bien d'autres trop laid pour décrire (imbrication, les événements, les tableaux de pointeurs de fonction, les fonctions de nommage Begin(), Moyen() et End() ...) .

Y a-t-il des modèles mieux conçus pour faire ce genre de chose?

+1

Je pense qu'un exemple plus spécifique pourrait susciter de meilleures réponses. Dans quelle mesure l'ordre dans lequel les choses doivent être faites est-il rigide? Si vous avez toujours besoin d'appeler certaines méthodes dans une séquence exacte, et ne pas le faire est une erreur ce qui ne va pas avec un void doEverything() qui les appelle toutes, dans le bon ordre. Si vous devez appeler des opérations dans des ordres ad hoc, quelles sont les contraintes? Pourquoi doivent-ils être appelés dans un ordre spécifique? fonctionnent-ils sur un état commun?ont-ils des effets secondaires, vous n'êtes pas un test unitaire? –

Répondre

1

Je suis confus pour expliquer pourquoi l'ordre est significatif si les tests unitaires ne seraient pas les attraper, et les dépendances ne sont pas explicitement dans le code; cela implique que les effets secondaires sont une partie cruciale de l'opération de foo() et de bar(). Dans ce cas, la meilleure stratégie de conception serait de rendre ces effets secondaires explicites!

+0

Alors, comment rendre les dépendances explicites? Est-ce la seule façon d'assurer le passage d'un test externe au corps du code, ou existe-t-il des moyens de rendre la séquence explicite? – lotsoffreetime

+0

Eh? Je veux dire dans le sens le plus littéral possible: File handle = function_a (filename); nombre d'enregistrements = fonction_b (identificateur de fichier); structure de données = fonction_c (identificateur de fichier, nombre d'enregistrements); Personne ne va changer l'ordre de ces ... –

+0

Toutes les séquences ne sont pas aussi évidentes. Qu'en est-il de get_price(); apply_discount (10%); add_tax(); Si la réduction est appliquée après l'ajout de la taxe, il y aura des problèmes et seul votre test unitaire (et votre compréhension de la logique métier) vous sauvera. Peut-être que la «logique métier de séquençage» est le phrasé que je recherche. – lotsoffreetime

0

Vous écrivez des tests unitaires pour vérifier ce qui s'est passé (état, changement d'attributs) après avoir appelé une procédure, donc je ne pense pas que vous ayez besoin de vérifier si une méthode a été appelée ou non. De plus, si vous liez votre test à une méthode, plus tard, si vous changez votre système pour utiliser une autre méthode avec les mêmes effets de foo(), votre test échouera même si votre système fait les bonnes choses.

Questions connexes