2010-09-28 4 views
1

J'ai une fonction somefunction() qui s'appelle beaucoup, mais la toute première fois qu'elle s'appelle je veux qu'elle se comporte un peu différemment. Voici un exemple:Comment approcher une fonction qui a un comportement légèrement différent lorsqu'elle est appelée la première fois?

first_time = true; 
somefunction(){ 
    // bunch of code... 
    if (first_time) 
    { 
    first_time = false; 
    // do it this way... 
    } 
    else 
    { 
    // do it that way... 
    } 
    // bunch of code... 
} 

3 approches viennent à l'esprit:

  • Vous pouvez faire comme dans l'exemple ci-dessus où vous la notion de « première fois » est explicite. Habituellement, la « première fois » chèque est un chèque booléen donc son très pas cher - mais encore, quand vous faites cela dans une minuterie qui déclenche de toutes les quelques centaines de millisecondes, il se sent pirater-ish.

  • Vous dupliquez la fonction et vous modifiez simplement les quelques lignes de code qui doivent être modifiées lors de son appel la première fois et appelez une fonction au début et l'autre fonction une fois sur deux. Surtout si la fonction est grande, cela semble vraiment moche IMO.

  • vous briser somefunction() et créer des fonctions distinctes pour lequel le code est exactement le même. Vous créez ensuite des fonctions wrapper pour la première fois et chaque fois que vous utilisez ces fonctions plus petites. Je pense que cette approche est la meilleure et est ce que je vais utiliser dans ma situation impliquant une minuterie.

Pensées?

+1

De quelle langue parlons-nous? – NullUserException

+0

Eh bien, je l'ai vu arriver beaucoup en C, où je suppose qu'il y a moins d'options pour écrire du code plus agréable ... – Suan

Répondre

0

Trop général; Je pense que la première et la troisième approche sont correctes dans une situation appropriée (le n ° 2 ne l'est pas - viole DRY). En outre, il ne montre pas maintes et maintes fois pour moi; le plus commun que je puisse penser est le modèle de singleton. Pouvez-vous donner un exemple précis?

0

La première approche semble très bien. La deuxième approche est un cauchemar de maintenance. La troisième approche semble être beaucoup plus compliquée qu'elle ne devrait l'être à partir de votre description. À moins que la décomposition des fonctions à ces points spécifiques fournisse un groupement logique, vous créerez simplement une solution de contournement qui pourrait même être plus désordonnée que deux. Une autre façon que je peux penser est d'utiliser une fonction de rappel pour exécuter le code "première fois" pour langues qui prennent en charge les fonctions en tant qu'objets de première classe. Voici un exemple en JavaScript.

function makeSpecialFunction = function(runOnlyFirstTime) { 
    return function() { 
     // code before 

     if(runOnlyFirstTime) { 
      runOnlyFirstTime(); 
      runOnlyFirstTime = null; 
     } 

     // code after 
    }; 
}; 

Pas une énorme amélioration, je sais, mais si la seule chose garder votre someFunction d'être réutilisable, alors ceci est votre solution.

maintenant someFunction peut être utilisé deux fois avec différents codes d'initialisation.

var init = function() { 
    alert("first:init"); 
}; 

var init2 = function() { 
    alert("first:init2"); 
}; 

var someFunction = makeSpecialFunction(init); 
var otherFunction = makeSpecialFunction(init2); 

someFunction(); // alerts first:init 
someFunction(); // doesn't alert anything 
0

Dans les langues comme C#, vous pouvez utiliser des délégués comme si (Fonction est la méthode appelable public):

public delegate void FunctionSignature(); 

class FunctionContainer 
{ 
    public FunctionSignature Function; 

    public FunctionContainer() 
    { 
    Function = FirstTimeFunction; 
    } 

    private void FirstTimeFunction() 
    { 
    ... 
    Function = FollowingTimesFunction; 
    } 

    private void FollowingTimesFunction() 
    { 
    ... 
    } 
} 

Juste une idée, une curiosité si vous voulez, mais il peut travailler pour vous: -)

0

L'option 1 est le scénario général le plus simple et le plus maintenable, l'OMI,.
Je passerais un paramètre first à la fonction par défaut false:

function(first = false) 
    if first 
    ... do something special 
    else 
    ... optionally do something else special (if you want) 
    ... do main stuff 

Je suis d'accord avec les opinions des autres que # 2 est en soi une mauvaise idée, et # 3 peut être surpuissant.

C'est généralement ce que les paramètres des fonctions sont pour agir sur eux et modifier le comportement basé sur eux. first pourrait tout aussi bien être last, is_weekday, am_i_feeling_lucky, etc.

0

C a des variables locales statiques dont les valeurs persistent d'invocation à l'invocation. Vous pouvez déclarer first_time comme une variable statique. Sa valeur sera initialisée sur le premier appel seulement. Les appels suivants utiliseront la valeur précédente. Ainsi, il devient un drapeau pour indiquer s'il s'agit de la première invocation ou non.

void some_function() 
{ 
    static int first_time = 1; 

    if (first_time) { 
     // do stuff for first call only 
     first_time = 0; 
    } 

    // do stuff for every call 
} 
0

Dans certaines situations, vous pourriez être en mesure d'utiliser un Sentinel Value, mais en sens inverse: à savoir, passer une valeur spéciale pour initialiser la fonction. Je pense que ces situations sont rares.

Mieux vaut probablement une variante de votre option 3: placer la fonction dans sa propre classe et faire en sorte que les étapes d'initialisation ne fassent pas partie de la fonction, mais plutôt une partie du constructeur de la classe. Il reste certaines situations que cela ne couvre pas - où la valeur initiale réelle est nécessaire pour l'initialisation, par exemple, mais je pense que cela couvre la plupart des cas et est l'option la plus propre. Même lorsque cette valeur initiale est nécessaire, vous pouvez peut-être la transmettre au constructeur, mais votre logique conditionnelle se déplace alors vers l'appelant, ce qui est probablement une mauvaise idée.

Questions connexes