J'écris une fonction R, qui devient assez grosse. Il admettait plusieurs choix, et je l'organise comme suit: J'ai deux questions: p> Si j'écris la sous-fonction, cela ressemblerait à ceci: p>
if(type == "aa" | type == "bb"){
- do something common to aa and bb -
if(type == "aa"){
- do something aa-related -
}
if(type == "bb"){
- do something bb-related -
}
}
if(type == "cc" | type == "dd"){
- do something common to cc and dd -
if(type == "cc"){
- do something cc-related -
}
if(type == "dd"){
- do something dd-related -
}
}
if(type == "zz"){
- do something zz-related -
}
4 Réponses :
Ceci est une question beaucoup plus générale sur la conception du programme. Il n'y a pas de réponse définitive, mais il y a presque certainement un meilleur itinéraire que ce que vous faites actuellement. P>
Ecrire des fonctions qui gèrent les différents types sont un bon itinéraire pour descendre. Dans quelle mesure cela dépendra-t-il de plusieurs choses - par exemple, combien de types différents y a-t-il? Sont-ils du tout liés, par exemple Certains d'entre eux pourraient-ils être traités par la même fonction, avec un comportement légèrement différent en fonction de l'entrée? P>
Vous devriez essayer de penser à votre code de manière modulaire. Vous avez une grande tâche à faire dans l'ensemble. Pouvez-vous le casser dans une séquence de tâches plus petites et écrire des fonctions qui effectuent les tâches plus petites? Pouvez-vous généraliser l'une de ces tâches d'une manière qui ne rend pas les fonctions (beaucoup) plus difficiles à écrire, mais leur donne une applicabilité plus large? P>
Si vous donnez plus de détails sur ce que votre programme est censé réaliser, nous pourrons vous aider davantage. P>
J'écris une fonction qui applique différents filtres à une image (filtre différent = différent "type" param). Certains filtres partagent certains codes (c'est-à-dire «AA» et «BB» sont deux filtres gaussiens, qui diffèrent uniquement pour un code de ligne), tandis que d'autres sont complètement différents. Donc, je suis obligé d'utiliser beaucoup d'if de déclaration IF, c'est-à-dire si (type == "AA" | Type == "BB") { Code> Faites quelque chose de commun à AA et BB i> si (type == "aa") { code> faire quelque chose aa-liée i> } if (type == "bb") { code> < i> faire quelque chose lié à bb i> }} si (type == "cc" | type == "dd") {... code>
@Tommaso Cette information supplémentaire devrait vraiment aller dans votre question, pas comme un commentaire à une réponse spécifique. Je vous suggère de mettre votre question à la place.
Une option est d'utiliser le commutateur code> au lieu de plusieurs Dans votre question modifiée, vous avez donné des informations beaucoup plus spécifiques. Voici un modèle de conception général que vous voudrez peut-être envisager. L'élément clé de ce modèle est qu'il n'y a pas un seul et appelez-le comme ceci: p> si code> instructions: p>
< H1> Option 2 H1> si code> en vue. Je le remplace par match.function code>, où l'idée de clé est que le type code> dans votre fonction est une fonction (oui, puisque R prend en charge la programmation fonctionnelle, cela est autorisé) .: p>
Cela semble plus élégant, donc merci pour la pointe. J'ai ajouté plus de détails dans les commentaires à Chris Taylor.
Andrie: La recommandation S3 est bonne, mais de nouveaux utilisateurs (et je compte moi-même dans ce groupe ;-)) Pourraient ne pas tout à fait attraper comment il peut être utilisé à la place d'un tas de si code> ou ou ou ou Commutateur code> Opérations. Pourriez-vous élaborer ou clarifier comment on peut utiliser le code S3 à la place? Cela pourrait peut-être être une réponse séparée, car elle est un peu plus longue.
@Iterator @Tommasso À la lumière de vos questions, j'ai modifié ma question avec un grand nouveau morceau expliquant l'utilisation de match.fun code>
Il n'y a guère jamais une raison pour ne pas refroidir votre code dans des fonctions plus petites. Dans ce cas, outre la réorganisation, il y a un avantage supplémentaire: l'utilisateur éduqué de votre (s) fonction (s) peut immédiatement appeler la sous-fonction si elle sait où elle est à. P>
Si ces fonctions ont beaucoup de paramètres, une solution (pour faciliter la maintenance) pourrait être de les regrouper dans une liste de classe "myconctionsparamètres", mais dépend de votre situation. P>
Si le code est partagé entre les différents sub_fun_xxs, il suffit de brancher que dans une autre fonction que vous utilisez à partir de chacun des SUB_FUN_XXS ou (si cela est viable) Calculez le trucs à l'avant et transmettez-le directement dans chaque sous_fun_xx. P >
Merci pour la réponse, il s'agit probablement de la meilleure solution à mon objectif. La seule chose que je ne comprends pas, c'est la raison pour laquelle réécrire le code partagé pour chaque sous-fonction est une méthode obsolète (supposant que si une sous-fonction fonctionne, l'autre ne le fera pas). Probablement pour une recommandation d'économie d'espace.
Imaginez qu'il existe une minuscule erreur dans le code partagé (ou une amélioration que vous ne pensez que quelques mois après la mise en œuvre initiale): Si vous répétez le code, vous devrez le modifier à plusieurs endroits.
Ceci est plus une question de programmation générale que la question R. En tant que tel, vous pouvez suivre les directives de base de la qualité du code. Il existe des outils pouvant générer des rapports de qualité de code de la lecture de votre code et vous donner des lignes directrices sur la manière d'améliorer. Un tel exemple est Gendarme pour le code .NET. Voici une ligne directrice typique qui apparaîtrait dans un rapport avec des méthodes trop longues: p>
En général, je "fusionner" un morceau de code s'il est réutilisable au moins deux fois. Sinon, votre approche initiale avec des morceaux de code à l'intérieur
si les déclarations code> semble raisonnable.Consultez ces questions sur Refactoring: Stackoverflow.com/questions/230706/Expling-factoring Stackoverflow.com/questions/5600257/... Stackoverflow.com/questions/498651/goals-of-factoring