Quelle est la différence entre les objets et les structures de données?


J'ai lu le livre Clean Code: Un manuel de l'artisanat Logiciel Agile et dans le chapitre six pages 95-98, il clarifie les différences entre les objets et les structures de données:

  • Les objets cachent leurs données derrière des abstractions et exposent les fonctions qui fonctionnent sur ces données. Les structures de données exposent leurs données et n'ont aucune fonction significative.

  • Objet exposer le comportement et masquer les données. Cela facilite l'ajout de nouveaux types de objets sans modifier les comportements existants. Il est également difficile d'ajouter de nouveaux comportements aux objets existants.

  • Les structures de données exposent les données et n'ont aucun comportement significatif. Cela facilite l'ajout de nouveaux comportements aux structures de données existantes, mais rend difficile l'ajout de nouvelles structures de données aux fonctions existantes.

Je suis un peu confus si certaines classes sont des objets ou des structures de données. Disons par exemple HashMaps en java.util, sont-ils des objets? (en raison de ses méthodes comme put(), get(), nous ne connaissons pas leur fonctionnement interne) ou sont-ils des structures de données? (Je l'ai toujours pensé comme des structures de données parce que c'est une carte).

Les chaînes aussi, sont-elles des structures de données ou des objets?

Jusqu'à présent la majorité du code que j'ai écrit ont été appelés "hybrides classes" qui tentent d'agir comme un objet et une structure de données ainsi. Des conseils sur la façon de les éviter ainsi?

Author: Nareg, 2014-05-01

9 answers

Un objet est une instance d'une classe. Une classe peut modéliser diverses choses du monde réel. C'est une abstraction de quelque chose (voiture, prise, carte, connexion, étudiant, enseignant, vous l'appelez).

Une structure de données est une structure qui organise certaines données d'une certaine manière. Vous pouvez implémenter des structures de manières différentes en utilisant des classes (c'est ce que vous faites dans des langages qui ne prennent pas en charge la POO, par exemple; vous pouvez toujours implémenter une structure de données en C, disons).

HashMap dans java est une classe qui modélise une structure de données cartographiques en utilisant une implémentation basée sur le hachage, c'est pourquoi elle s'appelle HashMap.

Socket en java est une classe qui ne modélise pas une structure de données mais autre chose (un socket).

 4
Author: peter.petrov, 2014-05-01 11:01:51

La distinction entre les structures de données et les classes/objets est plus difficile à expliquer en Java qu'en C++. En C, il n'y a pas de classes, seulement des structures de données, qui ne sont rien de plus que des "conteneurs" de champs typés et nommés. C++ a hérité de ces "structures", vous pouvez donc avoir à la fois des structures de données" classiques "et des"objets réels".

En Java, vous pouvez "émuler" des structures de données de style C en utilisant des classes qui n'ont pas de méthodes et uniquement des champs publics:

public class VehicleStruct
{
    public Engine engine;
    public Wheel[] wheels;
}

Un utilisateur de VehicleStruct connaît les pièces dont un véhicule est fait et peuvent interagir directement avec ces pièces. Le comportement, c'est-à-dire les fonctions, doit être défini en dehors de la classe. C'est pourquoi il est facile de changer de comportement: l'ajout de nouvelles fonctions ne nécessitera pas de changement de code existant. La modification des données, en revanche, nécessite des changements dans pratiquement toutes les fonctions interagissant avec VehicleStruct. Il viole l'encapsulation!

L'idée derrière la POO est de cacher les données et d'exposer le comportement à la place. Il se concentre sur ce que vous pouvez faire avec un véhicule sans avoir à savoir s'il a un moteur ou combien de roues sont installées:

public class Vehicle
{
    private Details hidden;

    public void startEngine() { ... }
    public void shiftInto(int gear) { ... }
    public void accelerate(double amount) { ... }
    public void brake(double amount) { ... }
}

Remarquez comment le Vehicle peut être une moto, une voiture, un camion, ou un réservoir -- vous n'avez pas besoin de connaître les détails. Changer les données est facile-personne en dehors de la classe ne connaît les données, donc aucun utilisateur de la classe n'a besoin d'être changé. Changer de comportement est difficile: toutes les sous-classes doivent être ajustées lorsqu'une nouvelle fonction (abstraite) est ajoutée à la classe.

Maintenant, suivant le "règles d'encapsulation" , vous pouvez comprendre cacher les données comme simplement rendre les champs privés et ajouter des méthodes d'accesseur à VehicleStruct:

public class VehicleStruct
{
    private Engine engine;
    private Wheel[] wheels;

    public Engine getEngine() { return engine; }
    public Wheel[] getWheels() { return wheels; }
}

Dans son livre, Oncle Bob soutient qu'en faisant cela, vous avez toujours une structure de données et non un objet. Vous êtes toujours en train de modéliser le véhicule comme la somme de ses pièces et d'exposer ces pièces à l'aide de méthodes. C'est essentiellement la même chose que la version avec des champs publics et un vieux C struct - d'où une structure de données. Cacher des données et exposer des méthodes ne suffit pas pour créer un objet, vous devez considérer si les méthodes exposent réellement comportement ou simplement les données!

Lorsque vous mélangez les deux approches, par exemple, l'exposition getEngine() avec startEngine(), vous vous retrouvez avec un "hybride". Je n'ai pas le livre de Martin à portée de main, mais je me souviens qu'il ne recommandait pas du tout les hybrides, car vous vous retrouvez avec le pire des deux mondes: des objets où les données et le comportement sont difficiles à changer.

Vos questions concernant les HashMaps et les chaînes sont un peu délicates, car elles sont de niveau assez bas et ne correspondent pas très bien aux types de classes que vous allez écrire pour vos applications. Néanmoins, en utilisant les définitions données ci-dessus, vous devriez pouvoir y répondre.

Un HashMap est un objet. Il vous expose son comportement et cache tous les détails de hachage désagréables. Vous le dites aux données put et get, et ne vous souciez pas de la fonction de hachage utilisée, du nombre de "compartiments" et de la manière dont les collisions sont gérées. En fait, vous utilisez HashMap uniquement via son interface Map, ce qui est une assez bonne indication de l'abstraction et des objets "réels".

Ne peut pas se confondre que vous pouvez utiliser instances d'une Carte en remplacement d'une structure de données!

// A data structure
public class Point {
    public int x;
    public int y;
}

// A Map _instance_ used instead of a data structure!
Map<String, Integer> data = new HashMap<>();
data.put("x", 1);
data.put("y", 2);

A String, d'autre part, est à peu près un tableau de caractères, et n'essaie pas beaucoup de cacher cela. Je suppose que l'on pourrait appeler une structure de données, mais pour être honnête, je ne sais pas si beaucoup à gagner d'une manière ou d' l'autre.

 13
Author: Ferdinand Beyer, 2016-01-30 09:21:20

Comme je le vois , ce que Robert Martin essaie de transmettre, c'est que les objets ne doivent pas exposer leurs données via des getters et des setters à moins que leur seul but soit d'agir comme de simples conteneurs de données. De bons exemples de tels conteneurs peuvent être des beans java, des objets d'entité (à partir du mappage d'objets d'entités DB), etc.

Les classes Java Collection Framework, cependant, ne sont pas un bon exemple de ce à quoi il fait référence, car elles n'exposent pas vraiment leurs données internes (ce qui est dans beaucoup de cas basique tableau). Il fournit une abstraction qui vous permet de récupérer les objets qu'ils contiennent. Ainsi (dans mon POV), ils entrent dans la catégorie "Objets".

Les raisons sont énoncées par les citations que vous avez ajoutées du livre, mais il y a plus de bonnes raisons de s'abstenir d'exposer les internes. Les classes qui fournissent des getters et setters invitent les violations de la loi de Demeter, par exemple. En plus de cela, connaître la structure de l'état d'une classe (savoir quels getters/setters elle a) réduit le capacité à abstraire l'implémentation de cette classe. Il y a beaucoup plus de raisons de ce genre.

 3
Author: eitanfar, 2014-05-01 12:09:42

C'est ce que, je crois, Robert. C. Martin essayait de transmettre:

  1. Les structures de données sont des classes qui agissent simplement comme des conteneurs de données structurées. Par exemple:

    public class Point {
        public double x;
        public double y;
    }
    
  2. Les objets, quant à eux, sont utilisés pour créer des abstractions. Une abstraction est comprise comme:

    Une simplification de quelque chose de beaucoup plus compliqué qui se passe sous les couvertures La Loi des Abstractions qui fuient, Joel on Logiciel

    Ainsi, les objets cachent tous leurs fondements et ne vous permettent que de manipuler l'essence de leurs données de manière simplifiée. Par exemple:

    public interface Point {
        double getX();
        double getY();
        void setCartesian(double x, double y);
        double getR();
        double getTheta();
        void setPolar(double r, double theta);
    }
    

    Où nous ne savons pas comment le Point est mise en œuvre, mais nous savons comment consommer il.

 2
Author: Enrique, 2015-08-05 22:02:31

Un structure de données est littéralement une représentation structurée des données. Il n'a aucune "connaissance" intégrée autre que la structure et la dénomination des données. Un object est beaucoup plus général et pourrait vraiment être presque n'importe quelle entité de votre système qui présente une interface d'interaction et peut être utilisée dans différents contextes. Plus précisément, un objet traditionnel class, par exemple, peut contenir des données et des méthodes appropriées pour accéder aux données, et ces données peut être spécifique à une instance d'objet (par instance) ou au niveau de la classe.

Je ne suis pas sûr du terme "classe hybride" basé sur la description d'agir en tant qu'objet ou structure de données car une classe inclut souvent des données. Cette terminologie semble donc redondante.

 1
Author: lurker, 2014-05-01 11:02:28

Une structure de données n'est qu'une abstraction, une manière particulière de représenter les données. Ce ne sont que des constructions faites par l'homme, qui aident à réduire la complexité au haut niveau, c'est-à-dire à ne pas travailler au bas niveau. Un objet peut sembler signifier la même chose, mais la différence majeure entre les objets et les structures de données est qu'un objet peut abstraire n'importe quoi. Il offre également un comportement. Une structure de données n'a aucun comportement car il s'agit simplement de mémoire contenant des données.

Les bibliothèques classes telles que Carte,Liste, etc. sont des classes, qui représentent structures de données. Ils implémentent et configurent une structure de données afin que vous puissiez facilement travailler avec eux dans vos programmes en créant des instances d'entre eux (c'est-à-dire des objets).

 1
Author: Sumanth, 2014-05-01 11:09:09

Les structures de données(DS) sont une façon abstraite de dire qu'une structure contient des données'. HashMap avec quelques paires clé valeur est une structure de données en Java. Les tableaux associés sont similaires en PHP, etc. Objets est un peu plus bas que le niveau DS. Votre hashmap est une structure de données. maintenant, pour utiliser un hashmap, vous en créez un "objet" et ajoutez des données à cet objet à l'aide de la méthode put. Je peux avoir mon propre employé de classe qui a des données et est donc un DS pour moi. Mais pour utiliser cette DS pour faire certaines opérations comme o voir si l'employé est un collègue de sexe masculin ou féminin, j'ai besoin d'une instance d'employé et de tester sa propriété de genre.

Ne confondez pas les objets avec les structures de données.

 0
Author: Nazgul, 2014-05-01 11:05:40

Votre question est étiquetée comme Java, donc je ne ferai référence qu'à Java ici. Les objets sont la classe Eve en Java; c'est-à-dire que tout en Java étend Object et object est une classe.

Par conséquent, toutes les structures de données sont des Objets, mais tous les objets ne sont pas des structures de données.

La clé de la différence est le terme Encapsulation.

Lorsque vous créez un objet en Java, il est considéré comme la meilleure pratique de rendre tous vos membres de données privés. Vous faites cela pour les protéger de toute personne utilisant la classe.

Cependant, vous voulez que les gens puissent accéder aux données, parfois les modifier. Vous fournissez donc des méthodes publiques appelées accesseurs et mutateurs pour leur permettre de le faire, également appelées getters et setters. De plus, vous voudrez peut-être qu'ils affichent l'objet dans son ensemble dans un format de votre choix, afin que vous puissiez définir une méthode toString; cela renvoie une chaîne représentant les données de l'objet.

Une structure est légèrement différente.

C'est une classe.

C'est un objet.

Mais il est généralement privé dans une autre classe; Car un nœud est privé dans un arbre et ne doit pas être directement accessible à l'utilisateur de l'arbre. Cependant, à l'intérieur de l'objet arbre, les membres de données des nœuds sont visibles publiquement. Le nœud lui-même n'a pas besoin d'accesseurs et de mutateurs, car ces fonctions sont approuvées et protégées par l'objet tree.

Mots-clés à rechercher: Encapsulation, Modificateurs de visibilité

 -1
Author: Mikeologist, 2014-05-01 12:27:46

Un objet est une instance d'une classe. Une classe peut définir un ensemble de propriétés/champs dont chaque instance/objet de cette classe hérite. Une structure de données est un moyen d'organiser et de stocker des données. Techniquement, une structure de données est un objet, mais c'est un objet avec l'utilisation spécifique pour contenir d'autres objets (tout en Java est un objet, même les types primitifs).

Pour répondre à votre question, une chaîne est un objet et une structure de données. Chaque objet String que vous créez est une instance de la classe String. Une chaîne, telle que Java la représente en interne, est essentiellement un tableau de caractères et un tableau est une structure de données.

Toutes les classes ne sont pas des plans pour les structures de données, mais toutes les structures de données sont techniquement des objets, c'est-à-dire des instances d'une classe (spécialement conçues pour stocker des données), si cela a un sens.

 -1
Author: Ben Arnao, 2016-01-30 08:56:18