128 votes

Classes et fonctions

Les fonctions sont faciles à comprendre, même pour une personne n'ayant aucune expérience de la programmation, mais possédant des connaissances en mathématiques. En revanche, les classes semblent plus difficiles à appréhender.

Disons que je veux créer une classe/fonction qui calcule l'âge d'une personne en fonction de son année de naissance et de l'année en cours. Dois-je créer une classe pour cela, ou une fonction ? Ou bien le choix dépend-il du scénario ?

P.S. Je travaille sur Python, mais je suppose que la question est générique.

220voto

Amber Points 159296

Créez une fonction. Fonctions faire des choses spécifiques, des classes sont des choses spécifiques.

Les classes ont souvent des méthodes, qui sont des fonctions associées à une classe particulière, et font des choses associées à la chose que la classe est - mais si tout ce que vous voulez est de faire quelque chose, une fonction est tout ce dont vous avez besoin.

Essentiellement, une classe est un moyen de regrouper des fonctions (en tant que méthodes) et des données (en tant que propriétés) en une unité logique tournant autour d'un certain type de chose. Si vous n'avez pas besoin de ce regroupement, il n'est pas nécessaire de créer une classe.

42voto

Maxime Lorant Points 11202

Comme quoi Amber dit dans sa réponse : créer une fonction. En fait, lorsque vous Ne le fais pas. doivent faire des cours si vous avez quelque chose comme :

class Person(object):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

    def compute(self, other):
        """ Example of bad class design, don't care about the result """
        return self.arg1 + self.arg2 % other

Ici, vous avez juste une fonction encapsulée dans une classe. Cela rend le code moins lisible et moins efficace. En fait, la fonction compute peut être écrit comme ceci :

def compute(arg1, arg2, other):
     return arg1 + arg2 % other

Vous ne devriez utiliser les classes que si vous leur attribuez plus d'une fonction et si le fait de conserver un état interne (avec des attributs) a un sens. Sinon, si vous voulez regrouper des fonctions, il suffit de créer un module dans un nouveau fichier .py archivo.

Vous pouvez regarder cette vidéo (Youtube, environ 30 minutes). ce qui explique mon point de vue. Jack Diederich montre pourquoi les classes sont diaboliques dans ce cas et pourquoi c'est une si mauvaise conception, surtout dans des choses comme les API.
C'est une vidéo assez longue, mais il faut la voir.

24voto

ulf Points 1039

Je sais qu'il s'agit d'un sujet controversé, et je risque de me faire griller maintenant. mais voici mes réflexions.

Pour ma part, je me suis dit que le mieux était d'éviter les cours le plus longtemps possible. Si j'ai besoin d'un type de données complexe, j'utilise un simple struct (C/C++), dict (python), JSON (js), ou similaire, c'est-à-dire pas de constructeur, pas de méthodes de classe, pas de surcharge d'opérateur, pas d'héritage, etc. Lorsque vous utilisez des classes, vous pouvez vous laisser emporter par la POO elle-même (quel modèle de conception, ce qui doit être privé, bla bla), et perdre de vue les éléments essentiels que vous vouliez coder en premier lieu.

Si votre projet prend de l'ampleur et devient désordonné, la POO commence à prendre tout son sens, car une sorte d'architecture système à vue d'hélicoptère est nécessaire. "Fonction vs classe" dépend également de la tâche qui vous attend.

fonction

  • objectif : traiter les données, manipuler les données, créer des ensembles de résultats.
  • quand l'utiliser : codez toujours une fonction si vous voulez faire ceci : "y=f(x)"

struct/dict/json/etc (au lieu de class)

  • but : stocker attr./param., maintenir attr./param., réutiliser attr./param., utiliser attr./param. plus tard.
  • quand l'utiliser : si vous traitez un ensemble d'attributs/paramètres (de préférence non mutables)
  • différents langages même chose : struct (C/C++), JSON (js), dict (python), etc.
  • préférez toujours les structures/dict/json/etc simples aux classes compliquées (restez simple !)

classe (s'il s'agit d'un nouveau type de données)

  • une perspective simple : est un struct (C), dict (python), json (js), etc. avec des méthodes attachées.
  • La méthode ne doit avoir de sens qu'en combinaison avec les données/paramètres stockés dans la classe.
  • mon conseil : ne jamais coder des choses complexes dans les méthodes de classe (appelez plutôt une fonction externe)
  • avertissement : n'utilisez pas les classes comme faux espaces de noms pour les fonctions ! (cela arrive très souvent !)
  • autres cas d'utilisation : si vous voulez faire beaucoup de surcharge d'opérateurs, utilisez des classes (par exemple, votre propre classe de multiplication de matrice/vecteur).
  • demandez-vous : s'agit-il vraiment d'un nouveau "type de données" ? (Oui => classe | Non => pouvez-vous éviter d'utiliser une classe)

tableau/vecteur/liste (pour stocker un grand nombre de données)

  • objectif : stocker un grand nombre de données homogènes du même type, par exemple des séries chronologiques.
  • conseil n°1 : utilisez ce que votre langage de programmation a déjà. ne le réinventez pas.
  • conseil#2 : si vous voulez vraiment votre "classe mysupercooldatacontainer", surchargez une classe tableau/vecteur/liste/etc existante (par exemple "classe mycontainer : public std::vector ")

enum (classe d'enum)

  • Je le mentionne juste
  • conseil#1 : utilisez les enum et les switch-case au lieu de schémas de conception OOP surcompliqués.
  • conseil n°2 : utiliser des machines à états finis

18voto

liljoshu Points 617

Je vais sortir du troupeau pour cette fois. (Editer 7 ans plus tard : Je ne suis plus une voix isolée sur ce sujet, il y a un mouvement de codage entier pour faire exactement cela, appelé "Programmation fonctionnelle"). et fournir un point de vue alternatif :

Ne jamais créer de classes. Utilisez toujours des fonctions.

Edit : La recherche a montré à plusieurs reprises que les classes sont une méthode de programmation dépassée. Presque tous les documents de recherche sur le sujet se rangent du côté de la programmation fonctionnelle plutôt que de la programmation orientée objet.

La dépendance à l'égard des classes a une tendance significative à amener les codeurs à créer un code gonflé et lent. Les classes qui circulent (puisqu'elles sont des objets) nécessitent beaucoup plus de puissance de calcul que l'appel d'une fonction et le passage d'une chaîne ou deux. Des conventions de nommage appropriées pour les fonctions peuvent faire à peu près tout ce que la création d'une classe peut faire, avec une fraction seulement de la surcharge et une meilleure lisibilité du code.

Cela ne veut pas dire que vous ne devez pas apprendre à comprendre les cours. Si vous codez avec d'autres, les gens les utiliseront tout le temps et vous devrez savoir comment jongler avec ces classes. Écrire votre code pour qu'il repose sur des fonctions signifie que le code sera plus petit, plus rapide et plus lisible. J'ai vu d'énormes sites écrits en n'utilisant que des fonctions qui étaient vifs et rapides, et j'ai vu de minuscules sites aux fonctionnalités minimales qui s'appuyaient fortement sur des classes et se cassaient constamment. (Lorsque vous avez des classes qui étendent des classes qui contiennent des classes comme partie de leurs classes, vous savez que vous avez perdu tout semblant de maintenabilité facile).

En fin de compte, toutes les données que vous souhaitez transmettre peuvent être facilement traitées par les types de données existants.

Les classes ont été créées comme une béquille mentale et n'apportent rien. réel et le code trop compliqué qu'ils ont tendance à créer va à l'encontre de l'intérêt de cette béquille à long terme.

Edit : Mise à jour 7 ans plus tard... Récemment, un nouveau mouvement dans le codage a validé ce point exact que j'ai fait. Il s'agit du mouvement visant à remplacer la programmation orientée objet (POO) par la programmation fonctionnelle, et il est basé sur un grand nombre des mêmes problèmes que la POO. Il y a beaucoup de documents de recherche qui montrent les avantages de la programmation fonctionnelle par rapport à la programmation orientée objet. En plus des points que j'ai mentionnés, elle rend la réutilisation du code beaucoup plus facile, la correction des bogues et les tests unitaires plus rapides et plus faciles. Honnêtement, avec le grand nombre d'avantages, la seule raison de préférer la POO à la programmation fonctionnelle est la compatibilité avec le code existant qui n'a pas encore été mis à jour.

13voto

Bakuriu Points 22607

Cela dépend du scénario. Si vous uniquement vous voulez calculer l'âge d'une personne, utilisez une fonction puisque vous voulez mettre en œuvre une méthode de calcul de l'âge. simple comportement spécifique.

Mais si vous voulez créer un objet, qui contient la date de naissance d'une personne (et éventuellement d'autres données), permet de le modifier, alors le calcul de l'âge pourrait être l'une des nombreuses opérations liées à la personne et il serait judicieux d'utiliser une classe à la place.

Les classes offrent un moyen de fusionner certaines données et des opérations connexes. Si vous n'avez qu'une seule opération sur les données, en utilisant une fonction et en passant les données comme argument, vous obtiendrez un comportement équivalent, avec un code moins complexe.

Notez qu'une classe du type :

class A(object):
    def __init__(self, ...):
        #initialize
    def a_single_method(self, ...):
        #do stuff

n'est pas vraiment une classe, c'est seulement une fonction (compliquée). Une classe légitime devrait toujours avoir au moins deux méthodes(sans compter __init__ ).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X