J'ai cette fonction API:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Je n'aime pas ça. Parce que l'ordre des paramètres devient inutilement significatif. Il devient plus difficile d'ajouter de nouveaux champs. Il est plus difficile de voir ce qui se passe. Il est plus difficile de refactoriser la méthode en parties plus petites car cela crée une autre surcharge de transmission de tous les paramètres dans les sous-fonctions. Le code est plus difficile à lire.
J'ai eu l'idée la plus évidente: avoir un objet encapsulant les données et le faire circuler au lieu de passer chaque paramètre un par un. Voici ce que j'ai trouvé:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Cela a réduit ma déclaration API à:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Agréable. Cela semble très innocent, mais nous avons en fait introduit un énorme changement: nous avons introduit la mutabilité. Parce que ce que nous faisions auparavant était en fait de passer un objet anonyme immuable: des paramètres de fonction sur la pile. Maintenant, nous avons créé une nouvelle classe qui est très modifiable. Nous avons créé la possibilité de manipuler l'état de l' appelant . Ça craint. Maintenant je veux que mon objet soit immuable, que dois-je faire?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Comme vous pouvez le voir, j'ai recréé mon problème d'origine: trop de paramètres. Il est évident que ce n'est pas la voie à suivre. Qu'est ce que je vais faire? La dernière option pour obtenir une telle immuabilité est d'utiliser une structure "en lecture seule" comme celle-ci:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
Cela nous permet d'éviter les constructeurs avec trop de paramètres et d'atteindre l'immuabilité. En fait, il résout tous les problèmes (ordre des paramètres, etc.). Encore:
- Tout le monde (y compris FXCop et Jon Skeet) convient que l' exposition des champs publics est mauvaise .
- Eric Lippert et al disent que s'appuyer sur des champs en lecture seule pour l'immuabilité est un mensonge .
C'est à ce moment-là que j'ai été confus et j'ai décidé d'écrire cette question: Quelle est la manière la plus simple en C # d'éviter le problème de «trop de paramètres» sans introduire de mutabilité? Est-il possible d'utiliser une structure en lecture seule à cette fin sans avoir une mauvaise conception d'API?
CLARIFICATIONS:
- Veuillez supposer qu'il n'y a pas de violation du principe de responsabilité unique. Dans mon cas d'origine, la fonction écrit simplement des paramètres donnés dans un seul enregistrement DB.
- Je ne cherche pas une solution spécifique à la fonction donnée. Je recherche une approche généralisée de ces problèmes. Je suis spécifiquement intéressé à résoudre le problème de "trop de paramètres" sans introduire de mutabilité ou une conception terrible.
METTRE À JOUR
Les réponses fournies ici présentent différents avantages / inconvénients. Par conséquent, j'aimerais convertir cela en un wiki communautaire. Je pense que chaque réponse avec un exemple de code et des avantages / inconvénients ferait un bon guide pour des problèmes similaires à l'avenir. J'essaie maintenant de savoir comment faire.
DoSomeActionParameters
est un objet jetable, qui sera jeté après l'appel de la méthode.