Question

Si j'ajoute une nouvelle classe de cas, est-ce que cela signifie que je dois chercher dans tout le code correspondant à des motifs et savoir où la nouvelle classe a besoin d'être traitée? J'ai appris la langue récemment, et comme je l'ai lu quelques-uns des arguments pour et contre correspondance de motif, j'ai confus où il doit être utilisé. Voir les éléments suivants:

Pro: Odersky1 Odersky2

Con: Beust

Les commentaires sont assez bons dans chaque cas, aussi. Alors, est quelque chose d'être métacaractères excité ou quelque chose que je devrais éviter d'utiliser? En fait, je pense que la réponse est « ça dépend du moment où vous l'utilisez, » mais ce sont des cas d'utilisation positifs et ce sont quelques négatifs?

Était-ce utile?

La solution

Jeff, je pense que vous avez la bonne intuition: cela dépend

.

hiérarchies de classes orienté objet avec l'envoi de méthode virtuelle sont bonnes lorsque vous avez un ensemble relativement fixe des méthodes qui doivent être mises en œuvre, mais de nombreuses sous-classes potentielles qui pourraient hériter de la racine de la hiérarchie et mettre en œuvre ces méthodes. Dans une telle configuration, il est relativement facile d'ajouter de nouvelles sous-classes (mettre en œuvre juste toutes les méthodes), mais relativement difficile d'ajouter de nouvelles méthodes (vous devez modifier toutes les sous-classes pour vous assurer qu'ils respectent bien la nouvelle méthode).

Les types de données avec des fonctionnalités en fonction de correspondance de motif sont bons lorsque vous avez un ensemble relativement fixe de classes qui appartiennent à un type de données, mais de nombreuses fonctions potentielles qui fonctionnent sur ce type de données. Dans une telle configuration, il est relativement facile d'ajouter de nouvelles fonctionnalités pour un type de données (juste match de motif sur toutes ses classes), mais relativement difficile d'ajouter de nouvelles classes qui font partie du type de données (vous devez modifier toutes les fonctions qui correspondent à sur le type de données pour vous assurer qu'ils prennent en charge correctement la nouvelle classe).

L'exemple canonique pour l'approche OO est la programmation graphique. éléments GUI doivent supporter très peu de fonctionnalités (se dessiner sur l'écran est le strict minimum), mais de nouveaux éléments de l'interface graphique sont ajoutés tous les temps (boutons, tableaux, graphiques, curseurs, etc.). L'exemple canonique pour l'approche de filtrage est un compilateur. Les langages de programmation ont généralement une syntaxe relativement fixe, de sorte que les éléments de l'arbre de syntaxe changent rarement (voire jamais), mais de nouvelles opérations sur les arbres de syntaxe sont constamment ajoutés (plus rapides optimisations, analyse de type plus approfondie, etc.).

Heureusement, Scala vous permet de combiner les deux approches. classes de cas peuvent aussi bien être adapté modèle et de soutenir l'envoi de méthode virtuelle. Les cours réguliers soutiennent l'envoi de méthode virtuelle et peuvent être adaptés par motif définissant un extracteur dans l'objet compagnon correspondant. Il est au programmeur de décider quand chaque approche est appropriée, mais je pense que les deux sont utiles.

Autres conseils

Bien que je respecte Cédric, il est tout à fait tort sur cette question. La correspondance de motif de Scala peut être entièrement encapsulé des changements de classe quand on le souhaite. Il est vrai qu'un changement à une case class aurait besoin de changer tout cas correspondant à motif correspondant, ce n'est que lorsque vous utilisez ces classes de façon naïve.

Le modèle de Scala correspondant à toujours délègue au deconstructor de l'objet compagnon d'une classe. Avec une classe de cas, ce deconstructor est généré automatiquement (avec une méthode de fabrication dans l'objet compagnon), mais il est encore possible de passer outre cette version générée automatiquement. En tout temps, vous pouvez exercer un contrôle complet sur le processus de mise en correspondance de motif, isolant les motifs des changements potentiels dans la classe elle-même. Ainsi, la correspondance de modèle est simplement une autre façon d'accéder à des données de classe à travers le filtre d'encapsulation sûr, comme toute autre méthode.

Alors, l'opinion du Dr Odersky serait celui de faire confiance ici, en particulier étant donné le volume de la recherche qu'il a effectué dans le domaine de la programmation orientée objet et design.

Quant à savoir où il doit être utilisé, qui est tout à fait selon le goût. Si cela rend votre code plus concis et maintenable, utilisez-le! Dans le cas contraire, ne pas. Pour la plupart des programmes orientés objet, pattern matching est inutile. Cependant, je pense qu'une fois que vous commencez à intégrer des idiomes plus fonctionnels (Option, List, etc), vous trouverez que la correspondance de modèle permettra de réduire considérablement les frais généraux syntaxique ainsi que l'amélioration de la sécurité offerte par le système de type. En général, chaque fois que vous voulez extraire des données tout en testant simultanément une certaine condition (extraction par exemple une valeur de Some), correspondance de motif sera probablement d'utilisation.

La correspondance de motifs est certainement bon si vous faites la programmation fonctionnelle. En cas de OO, il y a des cas où il est bon. Dans l'exemple de Cédric lui-même, cela dépend de la façon dont vous affichez conceptuellement la méthode print(). Est-ce un comportement de chaque objet Term? Ou est-ce quelque chose en dehors d'elle? Je dirais qu'il est à l'extérieur, et est logique de faire des filtrages. D'autre part, si vous avez une classe Employee avec différentes sous-classes, il est un choix de conception pauvre pour faire la correspondance de modèles sur un attribut de celui-ci (dire le nom) dans la classe de base.

En outre pattern matching offre une façon élégante de déballer les membres d'une classe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top