Où, dans un système orienté objet, devriez-vous, le cas échéant, choisir des structures (de style C) plutôt que des classes?

9

C et très probablement de nombreuses autres langues fournissent un structmot - clé pour créer des structures (ou quelque chose de manière similaire). Ce sont (au moins en C), d'un point de vue simplifié comme les classes, mais sans polymorphisme, héritage, méthodes, etc.

Pensez à un langage orienté objet (ou multi paradigme) avec des structures de style C. Où les choisiriez-vous plutôt que les cours? Maintenant, je ne pense pas qu'ils doivent être utilisés avec la POO car les classes semblent remplacer leurs objectifs, mais je me demande s'il y a des situations où elles pourraient être préférées aux classes dans des programmes autrement orientés objet et dans quel genre de situations. Existe-t-il de telles situations?

Anto
la source
Quelle langue utilisez-vous? Que publiez-vous? La plupart des langages OO modernes, à l'exception de Java, prennent en charge les propriétés d'une manière ou d'une autre.
kevin cline

Réponses:

16

Il y a une distinction que j'ai vue dans certains livres entre les objets porteurs d'état et les objets fournissant des fonctionnalités. Les termes exacts diffèrent d'une source à l'autre. Mais d'une manière générale, les premiers se distinguent par leur tas de champs et tout un tas de simples paires getters-setters (et peut-être un constructeur).

Celles-ci sont particulièrement courantes en Java, pour les classes qui sont explicitement marquées comme "sérialisables".

Je dirais que ce type de classes a le plus de sens en tant que structures, si vous pensez qu'il n'est pas nécessaire de masquer directement les membres (par exemple, dans le cas de types imbriqués).

Uri
la source
1
Robert C Martin les appelle des "objets de transfert de données" dans Clean Code .
user16764
5

En C, il n'y a pas de classes, tout structcomme la façon de regrouper les données. En C ++, structc'est la même chose que classsauf que l'héritage et l'accès aux membres sont publicpar défaut plutôt que private. C # a également une sorte de struct, mais je ne connais pas assez C # pour commenter. Common Lisp a la defstructforme, qui fonctionne autant comme C structs que possible, compte tenu de la différence de langage, et elle est différente d'une classe Common Lisp Object System.

Il existe cependant une différence conceptuelle entre un ensemble de données associé et une classe réelle, et en C ++ structest souvent utilisé pour un ensemble de données, tandis qu'il classest utilisé pour des objets qui sont censés avoir leur propre comportement. À titre indicatif, je dirais que a classreprésente quelque chose sur lequel vous pouvez dire quelque chose d'utile, comme un invariant de classe, tandis que a structserait plus lâchement associé à des valeurs de données ne dépendant pas vraiment beaucoup d'autres.

David Thornley
la source
6
La différence entre a structet a classest plus significative en C # - la grande chose étant que a structest un type valeur et a classest un type référence. Microsoft recommande de ne pas utiliser un structsi le contenu sera supérieur à 16 octets environ.
Carson63000
0

À un niveau très basique, quelle est la différence entre une structure et une classe de données pure (qui n'a aucune fonctionnalité en dehors des accesseurs de propriété)?

Rien que l'empreinte mémoire vraiment.

biziclop
la source
0

La réponse acceptée est bonne. Je voudrais juste ajouter ...

Parfois, il vaut mieux mettre une méthode dans une classe. D'autres fois, il est préférable d'avoir une fonction externe dans laquelle la structure / classe est passée en tant que paramètre (même si vous faites du style OOP).

exemple de moment pour placer une méthode dans la classe: Rectangle.CaclulateArea ()

exemple de moment pour placer une fonction en dehors de la classe: Canvas.Draw (Rectangle rect)

vous pouvez mettre Draw () à l'intérieur du rectangle et cela fonctionnera. Mais le dessin est une opération dépendante du niveau. Vous ne dessineriez pas côté serveur, mais côté client. Draw () n'aurait même pas de sens d'exister sur le serveur. Cependant, "CalculateArea ()" est indépendant du niveau et est un véritable attribut du rectangle, il est donc préférable de l'inclure en tant que méthode membre.

mike30
la source
0

Pour moi, la grande différence est de savoir s'il existe un invariant de classe ou non.

Ou en d'autres termes: suis-je libre de changer n'importe quel champ en n'importe quelle valeur à tout moment? Si c'est le cas, c'est une structure; Sinon, c'est une classe.

L'exemple habituel d'une structure est un point 2D, avec juste un membre X et Y, qui peut avoir n'importe quelle valeur et est totalement indépendant l'un de l'autre. L'accès du public est acceptable.

Un exemple de classe est la combinaison d'un pointeur sur un tableau de caractères et d'un champ de longueur: la longueur dépend de la valeur du pointeur, et donc ce ne devrait pas être une structure. Les champs doivent être privés et l'accès doit passer par des setters et des getters pour garantir l'invariant de classe.

Sjoerd
la source
0

1) Réseau structs: structures qui sont transmises sur le fil.

Plus généralement et formellement, toute classe dont vous avez besoin pour être POD, trivial, standard-layout ou un concept connexe. Pour une excellente discussion de ces concepts, avec des exemples, voir cette réponse (c'est pour C ++ 11).

2) Des foncteurs (prédicats en particulier), que vous passeriez à des fonctions comme std::remove_if. Autrement dit, des classes similaires à / héritées std::binary_functionou similaires.

3) Concepts de méta-programmation, qui ne peuvent contenir que des constexprs et / ou des typedefs publics .

Edit: Remarque: Cette réponse s'applique aux classes C ++ vs aux structures.

haelix
la source