J'ai une fonction qui prend un ensemble de paramètres, puis les applique en tant que conditions à une requête SQL. Cependant, alors que je favorisais un tableau d'arguments unique contenant les conditions elles-mêmes:
function searchQuery($params = array()) {
foreach($params as $param => $value) {
switch ($param) {
case 'name':
$query->where('name', $value);
break;
case 'phone':
$query->join('phone');
$query->where('phone', $value);
break;
}
}
}
Mon collègue a préféré plutôt énumérer tous les arguments explicitement:
function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
Son argument était qu'en listant explicitement les arguments, le comportement de la fonction devient plus apparent - au lieu d'avoir à fouiller dans le code pour découvrir quel était l'argument mystérieux $param
.
Mon problème était que cela devient très verbeux lorsqu'il s'agit de nombreux arguments, comme 10+. Y a-t-il une pratique préférée? Mon pire scénario serait de voir quelque chose comme ceci:
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
la source
foreach
n'est pas nécessaire dans ce cas, vous pouvez utiliser à laif(!empty($params['name']))
place deforeach
etswitch
.!empty($params['name'])
pour tester les paramètres - par exemple, la chaîne «0» serait vide. Il vaut mieux utiliserarray_key_exists
pour vérifier la clé, ouisset
si vous ne vous souciez pasnull
.Réponses:
À mon humble avis, votre collègue a raison pour l'exemple ci-dessus. Votre préférence peut être concise, mais elle est également moins lisible et donc moins maintenable. Posez-vous la question de savoir pourquoi s'embêter à écrire la fonction en premier lieu, qu'est-ce que votre fonction «apporte à la table» - je dois comprendre ce qu'elle fait et comment elle le fait, en détail, juste pour l'utiliser. Avec son exemple, même si je ne suis pas un programmeur PHP, je peux voir suffisamment de détails dans la déclaration de fonction que je n'ai pas à me soucier de son implémentation.
En ce qui concerne un plus grand nombre d'arguments, cela est normalement considéré comme une odeur de code. En général, la fonction essaie d'en faire trop? Si vous trouvez un réel besoin pour un grand nombre d'arguments, il est probable qu'ils sont liés d'une manière ou d'une autre et appartiennent ensemble à une ou quelques structures ou classes (peut-être même un tableau d'éléments connexes tels que des lignes dans une adresse). Cependant, le passage d'un tableau non structuré ne résout rien aux odeurs de code.
la source
where
arguments, un pour lesjoin
spécificateurs, etc. En les nommant de manière appropriée, ce serait toujours auto-documenté.Ma réponse est plus ou moins indépendante de la langue.
Si le seul but de regrouper des arguments dans une structure de données complexe (table, enregistrement, dictionnaire, objet ...) est de les transmettre dans leur ensemble à une fonction, mieux vaut l'éviter. Cela ajoute une couche inutile de complexité et rend votre intention obscure.
Si les arguments groupés ont une signification par eux-mêmes, alors cette couche de complexité aide à comprendre l'ensemble du design: nommez-la plutôt couche d'abstraction.
Vous pouvez constater qu'au lieu d'une douzaine d'arguments individuels ou d'un grand tableau, la meilleure conception est de deux ou trois arguments regroupant chacun des données corrélées.
la source
Dans votre cas, je préférerais la méthode de votre collègue. Si vous écriviez des modèles et que j'utilisais vos modèles pour les développer. Je vois la signature de la méthode de votre collègue et je peux l'utiliser immédiatement.
Alors, je devrais passer par l'implémentation de votre
searchQuery
fonction pour voir quels paramètres sont attendus par votre fonction.Je préférerais votre approche uniquement dans le cas où le
searchQuery
est limité à la recherche uniquement dans une seule table, donc il n'y aura pas de jointures. Dans ce cas, ma fonction ressemblerait à ceci:Donc, je sais immédiatement que les éléments du tableau sont en fait les noms de colonnes d'une table particulière que la classe ayant cette méthode représente dans votre code.
la source
Faites les deux, en quelque sorte.
array_merge
permet une liste explicite en haut de la fonction, comme le souhaite votre collègue, tout en empêchant les paramètres de devenir trop lourds, comme vous préférez.Je suggère également fortement d'utiliser la suggestion de @ chiborg dans les commentaires de la question - c'est beaucoup plus clair ce que vous avez l'intention.
la source
Vous pouvez également passer une chaîne ressemblant à une chaîne de requête et utiliser
parse_str
(car il semble que vous utilisez PHP, mais d'autres solutions sont probablement disponibles dans d'autres langues) pour la traiter dans un tableau à l'intérieur de la méthode:et l'appelle comme
Vous pouvez utiliser
http_build_query
pour convertir d'un tableau associatif en une chaîne (l'inverse qui leparse_str
fait).la source