[Tuto] POO

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

[Tuto] POO

Message par cha0s »

je vais éviter de faire un n-ieme tuto sur la POO juste donner un exemple et donner quelques généralité.



Introduction

Bon pour éviter que ce soit lourds je vais donner des exemples puis donner des commentaires pour que ce soit claire.

premier exemple on va prendre une voiture.
Notre voiture possède un moteur des roues et des portes (oui c'est tout on ira pas plus loin sinon on a pas finit)

Nous avons donc les classes suivantes
-Voiture
-Roue
-Porte
-Moteur

une voiture comporte
-un moteur
-quatre roues
-deux portes(oui c'est une petite voiture :p)

ce qui donne le schéma suivant

Image

Bien sur il n'est pas complet il manque la liste des attributs des structures et la liste des procédures.

Code
Premiere Version
Voyons maintenant ce que sa donne en PureBasic mais sans utiliser d'interface plutôt lourde.


On commence par crées les attributs des Classes

Code : Tout sélectionner

Structure Roue
  Diametre.l
EndStructure

Structure Moteur
  Puissance.l
EndStructure

Structure Porte
  VitreTeinte.b
EndStructure

Structure Voiture
  *Roue.Roue[4]
  *Moteur.Moteur
  *Porte.Porte[2]
EndStructure
Une fois ceci fait on va créer les "méthodes" des Classes. Une méthodes est une procédure cependant elle est liée a un objet.

un objet ? c'est quoi ? c'est juste une allocation mémoire de la taille de la structure.

mais notre objet ne se construit pas par la bonne volonté du saint esprit c'est pourquoi pour chaque classe il faut un constructeur. Un constructeur c'est juste une procédure qui initialise l'objet.

On commence donc par la classe Roue et on écrit son constructeur.

Code : Tout sélectionner

Procedure NewRoue(Diametre.l)
  Protected *this.Roue = AllocateMemory(SizeOf(Roue))
  *this\Diametre = Diametre
  ProcedureReturn *this
EndProcedure
On peut désormais créer une Roue mais que peut ont fait sur une Roue ? heu la gonfler par exemple !

Code : Tout sélectionner

Procedure Roue_Gonfler(*this.Roue)
  Debug "Hop on a gonfléé la roue"
EndProcedure
comme je suis informaticien je suis faignant donc je vais créer un macro pour aller plus vite

Code : Tout sélectionner

Macro New(Type)
  Protected *this.Type = AllocateMemory(SizeOf(Type))
EndMacro

Procedure NewRoue(Diametre.l)
  New(Roue)
  *this\Diametre = Diametre
  ProcedureReturn *this
EndProcedure
je vous laisse faire les classes Moteur et Porte et compléter la classe Roue mais comme je suis gentils je vous offre la Classe Voiture histoire que vous sachiez quoi coder avec un exemple d'utilisation.

Code : Tout sélectionner

Procedure NewVoiture(Nom.s)
  New(Voiture)
  Select Nom
    Case "tingo"
      *this\Roue[0] = NewRoue(40)
      *this\Roue[1] = NewRoue(40)
      *this\Roue[2] = NewRoue(40)
      *this\Roue[3] = NewRoue(40)
      *this\Porte[0] = NewPorte(#False)
      *this\Porte[1] = NewPorte(#False)
      *this\Moteur = NewMoteur(60)
    Case "panda"
      *this\Roue[0] = NewRoue(20)
      *this\Roue[1] = NewRoue(20)
      *this\Roue[2] = NewRoue(20)
      *this\Roue[3] = NewRoue(20)
      *this\Porte[0] = NewPorte(#True)
      *this\Porte[1] = NewPorte(#True)
      *this\Moteur = NewMoteur(120);surpuissant la panda
    Case "fred"
      Debug "Oo"
      ProcedureReturn #Null
    Default
      Debug "hé sa existe pas sa"
      ProcedureReturn #Null
  EndSelect
  ProcedureReturn *this
EndProcedure

Procedure Voiture_Avancer(*this.Voiture)
  Debug "GPS en panne -_-"
EndProcedure

Procedure Voiture_Rouler(*this.Voiture)
  Protected n
  For n = 0 To 3
    Roue_Gonfler(*this\Roue[n])
  Next n
  Porte_Ouvrir(*this\Porte[0])
  Porte_Fermer(*this\Porte[0])
  Moteur_Demarer(*this\Moteur)
  Repeat 
    For n = 0 To 3
      If Roue_Creve(*this\Roue[n]) = #True
        Break
      EndIf
    Next n
    Voiture_Avancer(*this)
  ForEver
EndProcedure


Define.Voiture *MaVoiture = NewVoiture("panda")
Voiture_Rouler(*MaVoiture)
Nous allons nous arrêter quelques instant pour prendre du recul vis a vis de ce que nous venons de coder.

Intérêt ?

c'est bien jolie mais sa sert pas a grand chose ! Oui effectivement si vous avez toujours programmé en procédural l'intérêt au premier abord est plutôt limité, donc voici les avantages.

Première chose faciliter le travaille en équipe :
On définit les classes méthodes et procédure sur un schéma et on distribue le codage des classes entre les membres de l'équipe.

Seconde chose si on revient dans son code de 6 000 ligne trois mois après c'est très simple de se retrouver .

Troisio le problème est plus facile a modéliser en objet que en procédurale.

La POO n'est pas l'invention du siècle et n'est pas forcement adapté a tout le monde si vous et le procedurale c'est une histoire d'amour inutile de vous forcer a coder en POO., surtout pour les petits projets.


Seconde version
La seconde méthode pour coder ceci en POO est d'utiliser les interfaces. Il existe bien des tutos sur l'utilisation des interfaces donc je ne vais pas donner de détails mais je vous invite a aller faire un tour dans la section tuto si cela vous intéresse.

Si vous suivez le schéma plus haut vous devriez avoir quatre interface.


Troisieme version
Bon oui il existe une autre version c'est d'utiliser Chronos (oui j'en profite pour faire un peu de PUB :oops: ) c'est surtout pour la POO que je suis en train de coder la bête. A l'heure ou je vous parle ce n'est pas encore stable donc si il vous prenait une envie irrésistible de sauter dessus (on sait jamais) attendez au moins la béta.

Sous Chronos nous avons un jolie précompilateur qui permet de respecter au mieux un schéma UML sans dénaturer le PureBasic mais trêve de blabla je vais reprendre ce que nous avons codé plus haut.

Code : Tout sélectionner

Structure Roue
  Diametre.l
EndStructure

Procedure NewRoue(Diametre.l)
  Protected *this.Roue = AllocateMemory(SizeOf(Roue))
  *this\Diametre = Diametre
  ProcedureReturn *this
EndProcedure

Procedure Roue_Gonfler(*this.Roue)
  Debug "Hop on a gonfléé la roue"
EndProcedure
maintenant transformons ceci

Code : Tout sélectionner

Class Roue
  Diametre.l

  Procedure Roue(Diametre.l)
    *this\Diametre = Diametre
  EndProcedure
  
  Procedure Gonfler()
    Debug "Hop on a gonflée la roue de diamètre : " + str(*this\Diametre)
  EndProcedure

EndClass
On envoie sa au précompilateur et il crée pour nous la structure les procédures et les déclarations. Si vous ne l'avez par remarqué nous venons de gagner en lisibilité, le code est moins lourds et aussi pratique que si nous avions utilisé des interfaces mais cela ne s'arrête pas la.

En effet comme je n'ai pas inventé la roue je l'ai copié sur certain language que j'utilise souvent comme java ou c++.

pour utiliser notre classe deux méthodes.

la première est totalement interprété par le compilateur.

Code : Tout sélectionner

Define.Roue *ptr = New Roue() ;il est important de définir le pointeur comme une Roue sinon le précompilateur ne peut pas savoir d'où vient la méthode Gonfler()
*ptr.Gonfler()
sera équivalent a

Code : Tout sélectionner

*ptr=New_Roue()
Roue_Gonfler(*ptr)
Petit explication sur "New", c'est un mot clée utilisé par les langages objet pour dire que l'on fait appel au constructeurs. Dans notre classe Roue le constructeur doit avoir le même nom que la classes sinon le precompilateur prendra la procédure comme une méthode.

Comme je suis ultra faignant j'ai ajouté quelques astuces ce qui permet de faire ceci

Code : Tout sélectionner

Class Roue
  Diametre.l = 24
  
  Procedure Gonfler()
    Debug "Hop on a gonflée la roue de diamètre : " + str(*this\Diametre)
  EndProcedure

EndClass
ici plus de constructeurs, il sera crée automatiquement et la variable diamètre initialisé a 24 lors de la création mais vous n'êtes pas obligé de mettre de valeur par défaut car pure s'en occupe a votre place en initialisant les variables a 0.


Généralités

Ce qui va suivre vient de mes cours de génie logiciel donc vous n'êtes pas obligé de tout respecter c'est juste histoire de normaliser nos codes structuré en POO.

Première chose une Classe commence par une majuscule et un attribut et une méthode par une minuscules. Si votre attribut ou votre méthode est un mot composé il devrait être écrit de la maniérè suivante : monAttribut.

Pure ne fait pas la différence mais celui qui lit le code si !

Je vous conseille d'utiliser EnableExplicit (sous Chronos c'est ajouté par le précompilateur) et de protéger tout les variables de vos procédures grâce au mot clé "protected".

Geteur et Seteur

Sous ces noms barbares d'un anglicisme douteux se cache une normalisation qui fait que votre code objet est bien codé ou non. En effet en POO a moins que cela soit absolument nécessaire on ne peut se permettre d'accéder ou de modifier un attribut en dehors de la classe, c'est pourquoi on a inventé les méthodes magiques set et get.

Par exemple dans notre classe Roue si l'on veut changer de diamètre on peut faire *ptr\Diametre = #monNouveauDiametre mais en dehors de la classe c'est une hérésie.
il faut donc crée une méthode "setDiametre(nouveauDiametre)" pareil pour lire le diametre l'on doit créer une méthodes "getDiametre()".

Mais cela va ralentir nôtre code car on doit faire un appel de procédure ? Oui c'est exacte mais cela améliore la lisibilité du code, mais comme je vous le disait vous n'êtes pas obligé de prendre ceci au pied de la lettre.

Méthodes Statiques

Nous avons vue les méthodes, ces jolies procédures liées a une allocation mémoire que nous appelons objet. Oui mais il existe des procédures qui ne sont pas lié a un objet.

Exemple la fonction Sin(Angle.f) de pure basic elle n'est pas liée a un objet mais elle est liée a la classe Math c'est donc une méthode dite statique.
sous Chronos elle sont définie comme ceci.

Code : Tout sélectionner

Class Math
  Static Procedure sin(Angle.f)
    procedurereturn sin(Angle)
  EndProcedure
EndClass
debug Math::sin(24)
Vous êtes maintenant incollable sur la POO(enfin presque), alors prenons un exemple plus complexe.


le reste a venir ...
Dernière modification par cha0s le mer. 15/avr./2009 10:49, modifié 3 fois.
allasktulu
Messages : 34
Inscription : sam. 29/nov./2008 22:42

Message par allasktulu »

J'attend le reste avec impatience. :D
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message par cha0s »

Sa avance :). si vous avez des notes a ajouter n'hésitez pas et si vous trouvez des fautes dite le moi par PM car moi et le Français sa fait 5 (au moins).
Répondre