2010-07-21 2 views
1

Je suppose que je vais essayer d'expliquer ma question par 2 extraits de code:Implémentation des méthodes de classe: devrait-elle changer la variable membre d'une classe ou intégrer des arguments?

// snippet 1 
class FooBar 
{ 
    private int value; 

    public int DetermineSomeResult() 
    { 
     PerformSomeCalculationOnValue(); 
     PerformSomeMoreStuffOnValue(); 

     return value; 
    } 

    public int GetCachedValue() 
    { 
     return value; 
    } 
} 

La première mise en œuvre a essentiellement des méthodes qui fonctionne sur l'organe entier privé.

est ici la deuxième mise en œuvre

// snippet 2 
class FooBar2 
{ 
    private int value; 

    public int DetermineSomeResult() 
    { 
     int tempvalue =GetCachedValue(); 
     tempvalue = PerformSomeCalculationOnValue(tempvalue); 
     tempvalue = PeformMoreStuffOnValue(tempvalue); 

     SetValue(tempvalue); 
     return tempvalue; 
    } 

    public int GetCachedValue() 
    { 
     return value; 
    } 
} 

Pour la deuxième mise en œuvre, aucune modification est apportée à l'état interne jusqu'à ce que tous les calculs ont terminé. Design-sage lequel est le meilleur?

J'ai tendance à préférer le second car il est plus clair, montre les dépendances. Cependant, puisque la classe elle-même stocke déjà un membre de classe destiné à la valeur calculée, il semble stupide de ne pas l'utiliser.

Des commentaires à ce sujet?

+0

Votre préoccupation concerne-t-elle la sécurité des filetages? –

+0

Pas, pour l'instant. Mes projets ne concernent pas les discussions pour le moment. – Extrakun

Répondre

1

en utilisant des méthodes internes qui prennent des paramètres plutôt que de traiter une variable membre de classe mondiale pour cette classe que vous faites non seulement il est plus facile de test unitaire ces fonctions, mais vous réduisez aussi possibilité d'introduire des bugs dus à ce membre variabl e étant modifié hors séquence, en particulier si la classe a un comportement piloté par un thread d'événement ou de travail.

Donc je voudrais aller pour le deuxième exemple plutôt que le premier.

modifier Aussi, si votre langage de programmation les prend en charge, vous pouvez utiliser des pointeurs vers un type de variable donnée pour ces fonctions afin qu'ils deviennent (dans un code de style C psuedo):

DoSomeWorkOn(pointerto int); 

plutôt que

int newValue = DoSomeWorkOn(int oldValue); 
1

Je pense que vous face à un problème de conception décrit comme Command and state separation

bref je suggère que DetermineSomeResult() devrait calcule seulement une nouvelle valeur du champ « valeur » sans revenir et seule façon d'obtenir le " valeur » est par GetCachedValue()

public void DetermineSomeResult() 
{ 
    PerformSomeCalculationOnValue(); 
    PerformSomeMoreStuffOnValue(); 
    // consider "value" has already been set. 
} 

public int GetCachedValue() 
{ 
    return value; 
} 
1

Juste donné le code ci-dessus, les deux fonctionneraient.

Cependant, il y a un problème subtil ici dont j'aimerais parler. Dans le 1er cas, votre état interne peut être laissé dans un état incohérent. Cela peut se produire si les méthodes PerformSomeMoreStuffOnValue lève une exception avant de pouvoir définir l'état final de la valeur. La 2ème solution ne part pas dans un état incohérent sans prendre en compte d'autres choses qui peuvent être en jeu).

Questions connexes