43 votes

Apprendre la pensée orientée objet

Je travaille actuellement sur un petit moteur de jeu 2D en C++, mais je suis maintenant confronté à un démon - je suis nul pour concevoir un "système de classes" qui fonctionne vraiment. Il y a un blocage dans mon esprit qui m'empêche de voir où je devrais utiliser une classe et où je ne devrais pas. Je lisais un article sur la conception de moteurs et il proposait d'utiliser une classe 'State' pour gérer l'état des différentes entrées du jeu (j'utilisais un int). Il suggérait également que tous les objets du jeu (pas les objets io/vidéo/son, etc.) dérivent des classes Renderable ou NonRenderable. C'est intelligent. Je sais déjà que c'est une façon intelligente de faire les choses - je veux dire, chaque objet en Java est de la classe de base Object, n'est-ce pas ? Intelligent, je le sais ! Comment se fait-il que je ne l'ai pas fait de cette façon ? Que dois-je lire pour vraiment entrer dans cet état d'esprit ?

Un autre exemple. Je suis un cours d'été sur Ruby (vraiment simple) et nous sommes censés concevoir un camping. C'est simple ! Donc, un camping est une collection de 'parcelles' qui ont chacune une jauge électrique pour mesurer la quantité d'énergie consommée par le client. J'ai conçu trois classes, une pour le camping, qui à leur tour utilisent des tableaux de classes d'invités et de parcelles. Mon professeur m'a suggéré d'utiliser plus de classes. J'ai d'abord pensé : "WTF" ( !), où, quelles classes ? Tout était une classe à mon avis - jusqu'à ce que je réalise que la jauge devrait peut-être aussi être une classe ? Pour l'instant, la jauge est un Integer dans la classe Plot.

Je veux apprendre à trouver des solutions orientées objet à mes problèmes, et pas seulement à transformer les éléments les plus évidents en classes !

Conseils/livres/articles/blogs ?

Je suis en train de faire deux ans d'études supérieures en informatique et je programme comme passe-temps depuis de nombreuses années ! Je suis "juste" coincé - et cela m'empêche de créer un logiciel de plus grande envergure !

21voto

Daniel Daranas Points 15123

Mon expérience personnelle a été d'apprendre la construction de logiciels orientés objet avec Construction de logiciels orientés objet, 2e édition par Bertrand Meyer.

Ce livre m'a été d'une valeur inestimable à l'époque et reste le seul ouvrage qui m'a le plus appris en matière de programmation OO et de construction de logiciels en général.

Voici quelques-uns de ses points forts :

  • En Partie A : Les enjeux une très bonne définition de la qualité des logiciels.
  • En Partie B : La route vers l'orientation objet une recherche logique, étape par étape, des techniques d'OO, d'une manière qui fait croire au lecteur que l'enquête se fait en direct, c'est-à-dire comme s'il n'y avait pas encore de résultats connus. Cette partie vous permettra probablement d'acquérir l'état d'esprit que vous recherchez.
  • En Partie C : Techniques orientées objet Dans la partie technique du livre, vous consoliderez vos connaissances et apprendrez des techniques très utiles concernant la conception par contrat, l'héritage, la généricité, etc.
  • Partie D : La méthodologie OO : Bien appliquer la méthode est une approche plus pratique de la conception, que je trouve également très utile. Voir par exemple Comment trouver les classes (22) que vous pouvez trouver en ligne .

Après ces parties, viennent des sujets plus avancés, tels que Concurrence (30) o Bases de données (31) .

Puisque le livre utilise le Eiffel (conçu par l'auteur), cela vous mettra dans le bon état d'esprit et vous apprendra à penser. Il sera facile d'appliquer ces idées à d'autres langages de programmation, plus ou moins OO.

13voto

Dave Jarvis Points 12598

Orienté objet

La programmation orientée objet consiste à demander aux objets de faire quelque chose : un concept faussement difficile à appliquer correctement.

Goban

Considérez un plateau de jeu en 2D, comme pour jouer Allez sur (appelé goban ).

Pensez d'abord au comportement qu'il faut adopter pour accomplir sa tâche. Cela signifie qu'il faut dresser la liste des comportements d'un objet plutôt que de décider des données que les comportements manipulent. Par exemple, un tableau de base pourrait avoir les comportements suivants :

  • Placez une pierre de Go.
  • Retirer une pierre de Go.
  • Enlevez toutes les pierres.

Pour une version informatique du Go, il est pratique d'attirer l'attention sur des zones spécifiques :

  • Marquez une intersection (par exemple, triangle, chiffre, lettre, cercle, carré).
  • Supprimer une marque d'une intersection marquée.
  • Enlevez toutes les marques.

Notez qu'un goban n'a pas besoin de fournir un moyen de fournir aux clients une référence à la pierre à une intersection spécifique. Au lieu de cela, il peut répondre à des questions sur son état. Par exemple, une goban pourrait répondre aux questions suivantes :

  • Y a-t-il une pierre noire à une intersection donnée ?
  • Y a-t-il une pierre blanche à une intersection donnée ?
  • Y a-t-il une marque à une intersection donnée ?

Il n'est pas de la responsabilité de l goban pour connaître l'état du jeu : cela appartient à une instance d'une Jeu (qui a Règles ). Dans la vie réelle, un goban est simplement une scène pour les pierres.

A ce stade, nous pourrions écrire une interface pour une goban sans savoir comment l'implémentation sous-jacente fonctionnera.

public interface Goban {
  public void place( Stone stone, Point point );

  public void removeStone( Point point );
  public void removeStones();

  public void place( Mark mark, Point point );

  public void removeMark( Point point );
  public void removeMarks();

  public boolean hasWhiteStone( Point point );
  public boolean hasBlackStone( Point point );
  public boolean hasMark( Point point );
}

Remarquez comment la planche est proprement séparée des deux Règles y Jeux . Cela rend le goban réutilisable pour d'autres jeux (impliquant des pierres et des intersections). Le site goban pourrait hériter d'une interface générique (par exemple, une Conseil d'administration ), mais cela devrait suffire à expliquer une façon de penser en termes d'objets.

Encapsulation

Une mise en œuvre de la Goban n'expose pas ses données internes. À ce stade, je pourrais vous demander d'implémenter cette interface, d'écrire des tests unitaires et de m'envoyer la classe compilée lorsque vous aurez terminé.

Je n'ai pas besoin de savoir quelles structures de données vous avez utilisées. Je peux utiliser votre implémentation pour jouer sur (et représenter) un Goban. Il s'agit d'un point crucial que de nombreux projets ne maîtrisent pas. Beaucoup, beaucoup de projets codent ce qui suit :

public class Person {
  private HairColour hairColour = new HairColour( Colour.BROWN );

  public Person() {
  }

  public HairColour getHairColour() {
    return hairColour;
  }

  public void setHairColour( HairColour hairColour ) {
    this.hairColour = hairColour;
  }
}

C'est une encapsulation inefficace. Considérons le cas où Bob n'aime pas que ses cheveux soient colorés en rose. Nous pouvons faire ce qui suit :

public class HairTrickster {
  public static void main( String args[] ) {
    Person bob = new Person();
    HairColour hc = bob.getHairColour();
    hc.dye( Colour.PINK );
  }
}

Bob s'est maintenant fait colorer les cheveux en rose, et rien ne pouvait l'en empêcher. Il existe des moyens d'éviter cette situation, mais les gens ne les appliquent pas. Au lieu de cela, l'encapsulation est rompue, ce qui donne des systèmes rigides, inflexibles, truffés de bogues et impossibles à maintenir.

Une manière possible de renforcer l'encapsulation est de retourner un clone de HairColour . La classe Personne révisée rend maintenant difficile le changement de la couleur des cheveux en Rose.

public class Person {
  private HairColour hairColour = new HairColour( Colour.BROWN );

  public Person() {
  }

  public HairColour getHairColour() {
    return hairColour.clone();
  }

  public void setHairColour( HairColour hairColour ) {
    if( !hairColour.equals( Colour.PINK ) {
      this.hairColour = hairColour;
    }
  }
}

Bob peut dormir sur ses deux oreilles, sachant qu'il ne se réveillera pas avec une teinture rose.

9voto

j_random_hacker Points 28473

Il est bon de s'en souvenir : L'OO n'est pas une fin en soi. L'intérêt de l'OO est de rendre le développement et, surtout, maintenance de code plus facile pendant la durée de vie du produit. Méfiez-vous de la mentalité "OO pour le plaisir de l'OO".

6voto

chikak Points 954

Analyse et conception orientées objet (Head First)

J'aime les livres Head First parce qu'ils sont amusants à lire. Ils comportent des exercices et des puzzles pour se gratter la tête. J'ai lu ce livre et je l'ai trouvé très bon.

Le livre couvre :

  • Utiliser les principes OO (encapsulation et délégation)
  • Principe de l'ouverture et de la fermeture (OCP)
  • Le principe de responsabilité unique (PRU)
  • Modèles de conception, UML, cas d'utilisation, etc.

4voto

CiscoIPPhone Points 6151

Il y a un blocage dans mon esprit qui m'empêche de voir où je devrais utiliser une classe et où je ne devrais pas.

En fin de compte, les classes sont un moyen de séparer des systèmes complexes en parties simples qui interagissent les unes avec les autres. Essayez de créer des classes là où vous ne feriez que vous répéter.

Actuellement, la jauge est un nombre entier dans la classe Plot.

La jauge doit-elle être une classe ? Quel serait l'avantage de la transformer en classe ? C'est le genre de questions qu'il faut toujours se poser.

  1. Les moteurs de jeux sont difficiles à concevoir. La séparation d'exigences aussi vaguement définies est un processus complexe, à lire ici : article sur les moteurs de jeux
  2. La conception est itérative et vous refactorerez plusieurs fois, ne soyez pas surpris par cela.

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