Conception Orienté Objet : Avantages ou inconvénients ?
Conception Orienté Objet : Avantages ou inconvénients ?
J’aimerai lancer ici une réflexion sur les avantages et les inconvénients qu’apporterait un PureBasic proposant une conception Orienté Objet.
Le débat a été initié il y a peu sur le forum anglais ( voir ici, vous pouvez d’ailleurs participer à un vote).
Pourtant, personnellement mon opinion n’est pas faite, certainement par manque de pratique en OO.
Cependant pour l’avoir touché des doigts, l’OO me paraît satisfaisante du point de vue de l’esprit pour construire son code.
Puisque l’un des points communs des utilisateurs de Pure est disposer d’un langage le plus performant pour écrire rapidement un code, quel part l’OO peut apporter à PureBasic selon vous?
Le débat a été initié il y a peu sur le forum anglais ( voir ici, vous pouvez d’ailleurs participer à un vote).
Pourtant, personnellement mon opinion n’est pas faite, certainement par manque de pratique en OO.
Cependant pour l’avoir touché des doigts, l’OO me paraît satisfaisante du point de vue de l’esprit pour construire son code.
Puisque l’un des points communs des utilisateurs de Pure est disposer d’un langage le plus performant pour écrire rapidement un code, quel part l’OO peut apporter à PureBasic selon vous?
L'Orienté Objet à l'avantage de pouvoir modifier facilement l'organisation
des données sans modifier tout les programmes qui utilisent les même objet. Ça
permet de mettre à jour plus facilement le fonctionnement d'un programme.
Prenons le développement des Gadget dans PureBasic par exemple.
Est-ce qu'il est mieux que Fred donne directement la Structure qui contient toute
les informations sur les gadgets et qu'on fasse tout le travaille pour tout initialiser
correctement pour que ça fonctionne ?
Ou est-ce qu'il est mieux d'utiliser les commandes que Fred à fait pour creer des
gadget ou modifier le contenu des gadgets ?
Imaginer tout le travaille à faire si Fred doit modifier la Structure pour la création
des Gadget. (Remplacer des champs, en ajouter, en enlever, etc)
Ça voudrait dire ouvrir les 2 000 000 000 de code sources programmes pour faire
toute les mises à jour qui s'impose.
Tandis que si on utilise les commandes pour manipuler les gadgets et que Fred à
bien fait tout les mises à jour sur ces commandes alors les 2 000 000 000 de codes
sources vont encore compiler à quelques exceptions près.
C'est ça le but de la représentation caché et c'est pour cette raison que la POO
est apparue.
Alors oui, c'est beaucoup plus long à écrire le code en POO au départ, mais c'est
combien de fois plus rapide pour mettre à jour les codes.
En programmation, on écrit le code 1 fois et on le met à jour 10 000 fois.
Dans mon cas, ça fait un peu plus d'un an et demi que je travaille avec PB et je
fais encore aujourd'hui des mises à jour sur mes premiers programmes.
Parcontre la POO n'est vraiment nécessaire si le programme est tout petit. Un jeu
en 3D, en incluant le moteur 3D, l'intelligence artificielle, le moteur de jeu, etc
mérite d'être en OO. Ce sera plus facile de faire évoluer le développement du jeu,
de faire des amélioration et des mises à jour.
C'est mon point de vue sur la question.
A+
Guimauve
des données sans modifier tout les programmes qui utilisent les même objet. Ça
permet de mettre à jour plus facilement le fonctionnement d'un programme.
Prenons le développement des Gadget dans PureBasic par exemple.
Est-ce qu'il est mieux que Fred donne directement la Structure qui contient toute
les informations sur les gadgets et qu'on fasse tout le travaille pour tout initialiser
correctement pour que ça fonctionne ?
Ou est-ce qu'il est mieux d'utiliser les commandes que Fred à fait pour creer des
gadget ou modifier le contenu des gadgets ?
Imaginer tout le travaille à faire si Fred doit modifier la Structure pour la création
des Gadget. (Remplacer des champs, en ajouter, en enlever, etc)
Ça voudrait dire ouvrir les 2 000 000 000 de code sources programmes pour faire
toute les mises à jour qui s'impose.

Tandis que si on utilise les commandes pour manipuler les gadgets et que Fred à
bien fait tout les mises à jour sur ces commandes alors les 2 000 000 000 de codes
sources vont encore compiler à quelques exceptions près.
C'est ça le but de la représentation caché et c'est pour cette raison que la POO
est apparue.
Alors oui, c'est beaucoup plus long à écrire le code en POO au départ, mais c'est
combien de fois plus rapide pour mettre à jour les codes.
En programmation, on écrit le code 1 fois et on le met à jour 10 000 fois.
Dans mon cas, ça fait un peu plus d'un an et demi que je travaille avec PB et je
fais encore aujourd'hui des mises à jour sur mes premiers programmes.
Parcontre la POO n'est vraiment nécessaire si le programme est tout petit. Un jeu
en 3D, en incluant le moteur 3D, l'intelligence artificielle, le moteur de jeu, etc
mérite d'être en OO. Ce sera plus facile de faire évoluer le développement du jeu,
de faire des amélioration et des mises à jour.
C'est mon point de vue sur la question.
A+
Guimauve
J'ai convertis un moteur de lecture de fichiers mod (protracker) du Java en PureBasic tout en essayant de garder tout le côté orienté objet : cela montre que l'on peut "simuler" de l'OO.
L'avoir de manière native dans PureBasic ? Cela va sans dire : non.
Pourquoi ? Tout simplement parce qu'on s'éloignerais trop de l'esprit des langages basic.
Je suis pourtant tres orienté OO depuis que je m'y suis mis un peu plus sérieusement mais il faut savoir définir des limites quand à la conception et à l'avenir d'un langage : je ne pense pas qu'il soit saint de trop s'éloigner des objectifs que l'on s'est fixé, en tout cas, tant que tous ses objectifs ne sont pas atteints.
Par contre, proposer, plus tard, une version permettant de programmer en OO (via une lib par exemple) serait interessant.
Just my 2 cents.
L'avoir de manière native dans PureBasic ? Cela va sans dire : non.
Pourquoi ? Tout simplement parce qu'on s'éloignerais trop de l'esprit des langages basic.
Je suis pourtant tres orienté OO depuis que je m'y suis mis un peu plus sérieusement mais il faut savoir définir des limites quand à la conception et à l'avenir d'un langage : je ne pense pas qu'il soit saint de trop s'éloigner des objectifs que l'on s'est fixé, en tout cas, tant que tous ses objectifs ne sont pas atteints.
Par contre, proposer, plus tard, une version permettant de programmer en OO (via une lib par exemple) serait interessant.
Just my 2 cents.
"Qui baise trop bouffe un poil." P. Desproges
Merci déjà à Guimauve et KarLKoX pour votre réaction.
Après une recherche approfondit de ma part (voir notamment mon tuto sur le POO en PB), voici mon premier avis sur la question :
Le gros avantage de la POO se place sur l’obligation de conceptualiser son code. C’est à dire que l’on va pouvoir architecturer son code afin de faire des regroupements par concept de telle sorte que les redondances de codes soient limitées au possible.
Il en découle :
- Une meilleure vision du code (pour la lisibilité c'est différent
)
- Une meilleure maintenance (c’est l’un des points forts apprécié, notamment par l’industrie)
- Un travail en groupe facilité
etc…
Par contre, on devrait perdre en performance puisque les appels de fonctions (ici des méthodes) sont véritablement l’articulation du fonctionnement du programme.
D’autre part, le fait meme d’etre obligé à bien réfléchir à son code, peut prendre du temps et je comprends mieux qu’il soit plus pratique de faire du procédural sur des petits projets.
Cependant, réfléchir à son code, on y est tous obligé tout ou tard. Cette obligation est plus pressante en POO voila tout.
Personnellement, je pense qu’au fil de temps, le programmeur toujours plus expérimenté et amené assez naturellement à intégrer des concepts OO dans sa programmation, fusse sans s’en apercevoir
Après une recherche approfondit de ma part (voir notamment mon tuto sur le POO en PB), voici mon premier avis sur la question :
Le gros avantage de la POO se place sur l’obligation de conceptualiser son code. C’est à dire que l’on va pouvoir architecturer son code afin de faire des regroupements par concept de telle sorte que les redondances de codes soient limitées au possible.
Il en découle :
- Une meilleure vision du code (pour la lisibilité c'est différent

- Une meilleure maintenance (c’est l’un des points forts apprécié, notamment par l’industrie)
- Un travail en groupe facilité
etc…
Par contre, on devrait perdre en performance puisque les appels de fonctions (ici des méthodes) sont véritablement l’articulation du fonctionnement du programme.
D’autre part, le fait meme d’etre obligé à bien réfléchir à son code, peut prendre du temps et je comprends mieux qu’il soit plus pratique de faire du procédural sur des petits projets.
Cependant, réfléchir à son code, on y est tous obligé tout ou tard. Cette obligation est plus pressante en POO voila tout.
Personnellement, je pense qu’au fil de temps, le programmeur toujours plus expérimenté et amené assez naturellement à intégrer des concepts OO dans sa programmation, fusse sans s’en apercevoir

Je reviens sur le sujet parce que je n'y connais que trop peu à l'OO. Or, je viens de voir un petit exemple simple et concret que je vous poste ici.
Pour certains, ça ne leur apprendra rien, mais pour moi, tout ce qui touche à la souplesse d'un programme, je trouve ça intéressant.
Mettre en accord données et code en évitant les pièges du plantage, etc...
Pour certains, ça ne leur apprendra rien, mais pour moi, tout ce qui touche à la souplesse d'un programme, je trouve ça intéressant.
Mettre en accord données et code en évitant les pièges du plantage, etc...
Code : Tout sélectionner
;Created by <David.C#S4701L> 2007
;If you wish to redistribute please ask first! :)
;Official Topic: http://www.purebasic.fr/english/viewtopic.php?t=28818
Global oMax = 5 ;Your maximum amount of objects
Global Dim Object(oMax)
Enumeration
#Create
#Step
#Destroy
EndEnumeration
Procedure Test(InstanceId.l,Type.l=0)
Select Type
Case #Create ;Run straight after the object is made
MessageRequester("Hi","Hello there.")
Case #Step ;Run every "Step"
Debug "Object: Test - made event Step."
Case #Destroy ;Run when we want to remove the object
MessageRequester("MAYDAY!","I'm going down! I'm going down!!")
EndSelect
EndProcedure
Procedure EventInstance()
Repeat
For i=0 To oMax
If Object(i) <> 0
CallFunctionFast(Object(i),i,#Step)
EndIf
Next
Delay(16)
ForEver
EndProcedure
Procedure CreateInstance(CodeAddress.l)
For i=0 To oMax
If Object(i)=0
Object(i)=CodeAddress.l
CallFunctionFast(Object(i),i,#Create)
ProcedureReturn i
EndIf
Next
ProcedureReturn -1
EndProcedure
Procedure DestroyInstance(InstanceId)
For i=0 To oMax
If Object(i) = InstanceId
CallFunctionFast(Object(i),#Destroy)
Object(i) = 0
ProcedureReturn 1
EndIf
Next
ProcedureReturn
EndProcedure
Object1 = CreateInstance(@Test())
ObjectThreadID = CreateThread(@EventInstance(),"")
Repeat
Delay(16)
ForEver
Je pense que c'est parce qu'on manque d'exemples concrets sur les aspects bénéfiques de l'OO.
C'est pas évident de débarquer avec un gros projet pour exemple, dire «ben voilà, vous voyez ce gros code de bourbon, je souhaite ajouter telle fonctionnalité, voici comment je m'y prends. Voilà, c'est fait ! Maintenant je reprends ma version initiale et je reviens 6 mois plus tard, le temps de convertir le projet en procédural et de vous montrer après ces 6 mois de galère, comment je vais en chier pour ajouter ma nouvelle fonctionnalité en procédural !»
C'est pas évident de débarquer avec un gros projet pour exemple, dire «ben voilà, vous voyez ce gros code de bourbon, je souhaite ajouter telle fonctionnalité, voici comment je m'y prends. Voilà, c'est fait ! Maintenant je reprends ma version initiale et je reviens 6 mois plus tard, le temps de convertir le projet en procédural et de vous montrer après ces 6 mois de galère, comment je vais en chier pour ajouter ma nouvelle fonctionnalité en procédural !»
-
- Messages : 1202
- Inscription : sam. 31/déc./2005 23:52
D'accord avec toi, le procédural c'est pas du tout évolutif.Ollivier a écrit :«...vous montrer après ces 6 mois de galère, comment je vais en chier pour ajouter ma nouvelle fonctionnalité en procédural !»
Après quelques mois, je n'esseye même plus de retoucher mon code, surtout que j'ai la facheuse tendance à presque pas commenté tout ça...
C'est pour ça que je trouve la POO interessante, d'ailleur ça fait longtemp que je me suis dit que je mis esseyerais sur PB.
En procédural pour être évolutif il faut une programmation orientée composant. Après on peut faire évoluer les composants comme on le souhaite, mais il faut avoir à la base conçu son appli pour être évolutive sinon effectivement on bloque. L'objet et le procédural ne sont rien sans une architecture solide... Je préfère de loin un projet procédural bien conçu que le même objet et désordonné. La conception orientée objet a l'avantage sur procédural d'être plus facilement structurable mais pas forcément plus.
Dri
Dri
Saluw!
Bon, voici un code inspiré du précédent. Pour rester compatible avec les DLLs, il est au norme ISO 9000 Guimauve 2.
Bon, voici un code inspiré du précédent. Pour rester compatible avec les DLLs, il est au norme ISO 9000 Guimauve 2.
Code : Tout sélectionner
;{ Directives }
EnableExplicit
;}
;{ Constantes }
Enumeration
#CREATE
#EXTEND
#MANAGE
#REDUCE
#RESET
EndEnumeration
;}
;{ Mémoire }
Structure DWORD
DW.L[16384]
EndStructure
;}
;{ Objets }
Structure OBJDESC
Adress.L
EndStructure
Structure HOBJ
pList.L ; Pointe vers la liste des adresses des objets
Quant.L ; Quantité d'objets
Limit.L ; Limite du nombre d'objets avant réallocation de la table
pPipe.L ; Pointe vers le buffer E/S de l'objet (taille = SizeOf(OBJECTMANAGING) )
ID.L ; Index de l'objet en cours d'exécution
EndStructure
Structure OBJECTMANAGING
Action.L ; Doit toujours rester le 1er membre
Adress.L ; Doit toujours rester le 2nd membre
EndStructure
;{ Déclaration des objets }
Declare TestA(*hObj.HOBJ)
Declare TestB(*hObj.HOBJ)
;}
Procedure Objects(Action.L, *hObj.HOBJ)
With *hObj
Select Action.L
Case #CREATE
\pList = AllocateMemory(1024)
; SECURITY ^^
\Quant = 0
\Limit = 256
\pPipe = AllocateMemory(SizeOf(OBJECTMANAGING) )
Case #EXTEND
\Limit << 1
\pList = ReAllocateMemory(\pList, \Limit << 2)
; SECURITY ^^
Case #REDUCE
; SECURITY
\Limit >> 1
\pList = ReAllocateMemory(\pList, \Limit << 2)
Case #DELETE
FreeMemory(\pPipe)
FreeMemory(\pList)
FreeMemory(*hObj)
EndSelect
EndWith
EndProcedure
;}
;{ Objet }
Procedure Obj(*hObj.HOBJ)
Protected *Obj.OBJECTMANAGING
Protected *M.DWORD
Protected ID.L
Protected Base.L
With *hObj
*Obj = \pPipe
*M = \pList
Select *Obj\Action
Case #CREATE
*M\DW[\Quant] = *Obj\Adress
CallFunctionFast(*Obj\Adress, *hObj)
\Quant + 1
If \Quant = \Limit: Objects(#EXTEND, *hObj): EndIf
Case #MANAGE
\ID = 0
Repeat
CallFunctionFast(*M\DW[\ID], *hObj)
\ID + 1
Until \ID => \Quant
Case #DELETE, #RESET
For ID = 0 To \Quant - 1
If *M\DW[ID] = *Obj\Adress
CallFunctionFast(*Obj\Adress, *hObj)
Base = @*M\DW[ID]
MoveMemory(Base + SizeOf(OBJDESC), Base, ( (\Quant - ID) - 1) * SizeOf(OBJDESC) )
\Quant - 1
\ID - 1
EndIf
Next
If \Quant << 2 <= \Limit: Objects(#REDUCE, *hObj): EndIf
If *Obj\Action = #DELETE: *Obj\Action = #MANAGE: EndIf
EndSelect
EndWith
EndProcedure
;}
Procedure ObjectsStart()
Protected *hObj.HOBJ = AllocateMemory(SizeOf(HOBJ) )
; SECURITY ^^
Objects(#CREATE, *hObj)
Protected *Obj.OBJECTMANAGING = *hObj\pPipe
*Obj\Action = #CREATE
*Obj\Adress = @TestA(): Obj(*hObj)
*Obj\Adress = @TestB(): Obj(*hObj)
Repeat
*Obj\Action = #MANAGE
Obj(*hObj)
Until *Obj\Action = #RESET
*Obj\Action = #DELETE
*Obj\Adress = @TestA(): Obj(*hObj)
*Obj\Action = #DELETE
*Obj\Adress = @TestB(): Obj(*hObj)
Objects(#DELETE, *hObj)
EndProcedure
ObjectsStart()
; Si on arrive ici, c'est qu'il y a eu une action RESET
; Dans ce cas, toutes les zones mémoire utilisées sont libérées
; On peut écrire un programme habituel
;____________________________________________________________________________
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; Exemple avec 2 objets TestA() et TestB()
;____________________________________________________________________________
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Procedure TestA(*hObj.HOBJ)
Protected *Obj.OBJECTMANAGING = *hObj\pPipe
Select *Obj\Action
Case #CREATE
Debug "Bonjour"
Case #MANAGE
Debug "Coucou"
Case #DELETE
Debug "Au revoir"
EndSelect
EndProcedure
Procedure TestB(*hObj.HOBJ)
Protected *Obj.OBJECTMANAGING = *hObj\pPipe
Select *Obj\Action
Case #CREATE
Debug "Bonjour2"
Case #MANAGE
Debug "Coucou2"
*Obj\Action = #DELETE ; Ces 3 lignes tuent la procédure voisine dès le départ!
*Obj\Adress = @TestA() ; Commentez-les pour éviter ce drame
Obj(*hObj) ; Ou bien changez @TestA() en @TestB() pour obtenir un «suicide»
; *Obj\Action = #RESET ; En décommentant cette ligne, tout le programme objet est stoppé
; Chaque objet est détruit
Case #DELETE
Debug "Au revoir2"
EndSelect
EndProcedure