Parfois, nous devons écrire des méthodes qui reçoivent de nombreux arguments, par exemple:
public void doSomething(Object objA , Object objectB ,Date date1 ,Date date2 ,String str1 ,String str2 )
{
}
Quand je rencontre ce genre de problème, j'encapsule souvent des arguments dans une carte.
Map<Object,Object> params = new HashMap<Object,Object>();
params.put("objA",ObjA) ;
......
public void doSomething(Map<Object,Object> params)
{
// extracting params
Object objA = (Object)params.get("objA");
......
}
Ce n'est pas une bonne pratique, encapsuler des paramètres dans une carte est totalement un gaspillage d'efficacité. La bonne chose est, la signature propre, facile d'ajouter d'autres paramètres avec le moins de modifications. quelle est la meilleure pratique pour ce genre de problème?
Utiliser une carte avec des touches de chaîne magiques est une mauvaise idée. Vous perdez toute vérification du temps de compilation et les paramètres requis ne sont vraiment pas clairs. Vous auriez besoin d'écrire une documentation très complète pour compenser cela. Vous souviendrez-vous dans quelques semaines de ce que sont ces chaînes sans regarder le code? Et si vous faisiez une faute de frappe? Utilisez le mauvais type? Vous ne le saurez pas tant que vous n'aurez pas exécuté le code.
Utilisez plutôt un modèle. Créez une classe qui sera un conteneur pour tous ces paramètres. De cette façon, vous gardez la sécurité de type de Java. Vous pouvez également transmettre cet objet à d'autres méthodes, le placer dans des collections, etc.
Bien sûr, si l'ensemble de paramètres n'est pas utilisé ailleurs ou transmis, un modèle dédié peut être excessif. Il y a un équilibre à trouver, alors faites preuve de bon sens.
la source
Si vous avez de nombreux paramètres facultatifs, vous pouvez créer une API fluide: remplacez la méthode unique par la chaîne de méthodes
À l'aide de l'importation statique, vous pouvez créer des API internes fluides:
la source
Il s'appelle "Introduce Parameter Object". Si vous vous trouvez en train de passer la même liste de paramètres à plusieurs endroits, créez simplement une classe qui les contient tous.
Même si vous ne passez pas si souvent la même liste de paramètres, cette refactorisation facile améliorera toujours la lisibilité de votre code, ce qui est toujours bon. Si vous regardez votre code 3 mois plus tard, il sera plus facile à comprendre lorsque vous devez corriger un bogue ou ajouter une fonctionnalité.
C'est une philosophie générale bien sûr, et comme vous n'avez pas fourni de détails, je ne peux pas non plus vous donner de conseils plus détaillés. :-)
la source
XXXParameter param = new XXXParameter();
disponible, puis utiliserXXXParameter.setObjA(objA)
; etc ...Tout d'abord, j'essaierais de refactoriser la méthode. S'il utilise autant de paramètres, il peut être trop long de toute façon. Le décomposer améliorerait à la fois le code et réduirait potentiellement le nombre de paramètres de chaque méthode. Vous pourrez peut-être également refactoriser l'opération entière dans sa propre classe. Deuxièmement, je rechercherais d'autres cas où j'utilise le même (ou un sur-ensemble) de la même liste de paramètres. Si vous avez plusieurs instances, cela signifie probablement que ces propriétés appartiennent ensemble. Dans ce cas, créez une classe pour contenir les paramètres et utilisez-la. Enfin, j'évaluerais si le nombre de paramètres vaut la peine de créer un objet de carte pour améliorer la lisibilité du code. Je pense que c'est un appel personnel - il y a de la douleur dans chaque sens avec cette solution et le point de compromis peut différer. Pour six paramètres, je ne le ferais probablement pas. Pour 10, je le ferais probablement (si aucune des autres méthodes ne fonctionnait en premier).
la source
C'est souvent un problème lors de la construction d'objets.
Dans ce cas, utilisez un modèle d'objet de générateur , cela fonctionne bien si vous avez une grande liste de paramètres et que vous n'avez pas toujours besoin de tous.
Vous pouvez également l'adapter à l'appel de méthode.
Cela augmente également beaucoup la lisibilité.
Vous pouvez également insérer une logique de vérification dans les méthodes Builder set .. () et build ().
la source
final
? C'est la principale chose qui m'empêche d'écrire des fonctions d'aide. Je suppose que je peux rendre les champs privés et m'assurer de ne pas les modifier de manière incorrecte dans le code de cette classe, mais j'espère quelque chose de plus élégant.Il existe un modèle appelé objet Parameter .
L'idée est d'utiliser un objet à la place de tous les paramètres. Maintenant, même si vous devez ajouter des paramètres plus tard, il vous suffit de les ajouter à l'objet. L'interface de la méthode reste la même.
la source
Vous pouvez créer une classe pour contenir ces données. Doit être suffisamment significatif, mais bien mieux que d'utiliser une carte (OMG).
la source
Code Complete * suggère plusieurs choses:
* Première édition, je sais que je devrais mettre à jour. De plus, il est probable que certains de ces conseils aient changé depuis la rédaction de la deuxième édition, lorsque la POO commençait à devenir plus populaire.
la source
La bonne pratique serait de refactoriser. Qu'en est-il de ces objets signifie qu'ils doivent être passés à cette méthode? Devraient-ils être encapsulés dans un seul objet?
la source
L'utilisation d'une carte est un moyen simple de nettoyer la signature d'appel, mais vous avez un autre problème. Vous devez regarder à l'intérieur du corps de la méthode pour voir ce que la méthode attend dans cette Map, quels sont les noms de clés ou quels types les valeurs ont.
Une manière plus propre serait de regrouper tous les paramètres dans un bean objet, mais cela ne résout toujours pas complètement le problème.
Ce que vous avez ici est un problème de conception. Avec plus de 7 paramètres pour une méthode, vous commencerez à avoir des problèmes pour vous souvenir de ce qu'ils représentent et de leur ordre. De là, vous obtiendrez de nombreux bogues simplement en appelant la méthode dans le mauvais ordre des paramètres.
Vous avez besoin d'une meilleure conception de l'application et non d'une meilleure pratique pour envoyer de nombreux paramètres.
la source
Créez une classe bean, définissez tous les paramètres (méthode setter) et passez cet objet bean à la méthode.
la source
Regardez votre code et voyez pourquoi tous ces paramètres sont passés. Parfois, il est possible de refactoriser la méthode elle-même.
L'utilisation d'une carte rend votre méthode vulnérable. Que se passe-t-il si quelqu'un qui utilise votre méthode épelle mal un nom de paramètre ou publie une chaîne là où votre méthode attend un UDT?
Définissez un objet de transfert . Cela vous fournira au moins une vérification de type; il peut même être possible pour vous d'effectuer une validation au point d'utilisation plutôt que dans votre méthode.
la source
Ceci indique souvent que votre classe a plus d'une responsabilité (c'est-à-dire que votre classe en fait TROP).
Voir le principe de responsabilité unique
pour plus de détails.
la source
Si vous passez trop de paramètres, essayez de refactoriser la méthode. Peut-être qu'il fait beaucoup de choses qu'il n'est pas censé faire. Si ce n'est pas le cas, essayez de remplacer les paramètres par une seule classe. De cette façon, vous pouvez tout encapsuler dans une seule instance de classe et transmettre l'instance et non les paramètres.
la source
Je dirais de rester fidèle à la façon dont vous l'avez fait avant. Le nombre de paramètres dans votre exemple n'est pas grand, mais les alternatives sont bien plus horribles.
Carte - Il y a le problème d'efficacité que vous avez mentionné, mais le plus gros problème ici est:
autre chose ... Avez-vous des javadocs qui indiquent exactement quelles clés et
valeurs sont utilisées? Si vous le faites (ce qui est génial), avoir beaucoup de paramètres n'est pas non plus un problème.
Objets wrapper - cela ne fait que déplacer le problème puisque vous devez remplir l'objet wrapper en premier lieu - au lieu de directement dans votre méthode, ce sera vers le constructeur de l'objet paramètre. Déterminer si le déplacement du problème est approprié ou non dépend de la réutilisation dudit objet. Par exemple:
Je ne l'utiliserais pas: il ne serait utilisé qu'une seule fois lors du premier appel, donc beaucoup de code supplémentaire pour traiter 1 ligne ...?
Peut l'utiliser: Ici, il peut faire un peu plus. Premièrement, il peut factoriser les paramètres pour 3 appels de méthode. il peut également exécuter 2 autres lignes en lui-même ... donc il devient une variable d'état dans un sens ...
L'autre chose que les gens oublient de considérer est le rôle de l'IDE dans tout cela. Lorsque les méthodes ont des paramètres, les IDE génèrent la plupart du code pour vous, et vous avez des lignes rouges vous rappelant ce que vous devez fournir / définir. Lorsque vous utilisez l'option 3 ... vous perdez complètement cela. C'est maintenant au programmeur de faire les choses correctement, et il n'y a pas d'indices pendant le codage et la compilation ... le programmeur doit le tester pour le savoir.
En outre, les options 2 et 3, si elles sont adoptées largement inutilement, ont des implications négatives à long terme en termes de maintenance en raison de la grande quantité de code dupliqué qu'elles génèrent. Plus il y a de code, plus il y a à maintenir, plus on passe de temps et d'argent pour le maintenir.
la source