IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Création d'objets "par lots"


Sujet :

Langage Delphi

  1. #21
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr

    Oui moi aussi j'y vais souvent au feeling ... UML, Merise mon Q ! Au début je me laisse parfois abuser par leur méthodologie ... ah ouais ça a l'air pas mal, nouveau tout propre, pratique, structuré et puis ... mais ça va pas en fait !
    A force on finit par savoir si un truc à une chance de marcher ou au contraire de fouarrer

    j'avoue que parfois (souvent) je code aussi pour le fun

    Faut dire que comme maintenant je suis devenu expert avec D7 (bon comme personne ne me le dira jamais faut bien que je le dise moi même ) c'est de plus en plus facile de coder from scratch ...

    Ouais des Frameworks tout fait ça existe je sais. Je ne pense pas être atteint du "not invented here syndrom" encore que Mais on consacre tellement de temps à essayer de comprendre le pourquoi du comment qu'on finit par se poser des questions : ça vaut le coup d'insister ou vaut-il mieux le développer soi même ?


    si tu charge 10000 objets, eh bien, tu lance 50 000 000 fois la comparaison !!!

    Hé hé hé pas vraiment car d'une part la complexité de la recherche binaire est
    seulement O(log 2^n) d'autre part je teste au début si l'élémént que j'ajoute
    est déjà plus grand que le dernier de la liste (t'as pas idée comme ca accélère )
    Et n'oublions pas le fait que la table est vide au départ et crois de 0 à 10000
    Et si ça ne suffit pas j'utiliserais un arbre binaire de recherche en O(log n)
    Non mais, on va pas se laisser emm... par une recherche qd même !

    Enfin mes listes savent gérer le begin/end update (hé oui les bonnes idées je les reprends) de façon à ne pas émettre de notification lors d'un traitement long. D'ailleurs tous mes objets intègrent cette notion.
    De toute façon pour l'instant je n'émets aucun message de notification car je ne les ai pas implémenté.


    Sur un Dual Core à 2.6 Ghz j'instancie jusqu'à 400 000 objets par seconde : cet objet gère les interfaces et ne comporte que 4 ou 5 champs de type simple dont 1 seul string donc des objets quasiment vides et sans traitement complexe à la création. Et je les ajoute bel et bien dans la liste.
    D'ailleurs mon TObjectManager me l'indique clairement : 400007 objets et ça occupe 30Mo en RAM ha quand même !

    Mais pour mes attributs (que j'ai finalement renommés "membres" pour le cas où je passerais sur .net) j'ai pensé à faire autrement sans objets du tout mais en utilisant des pointeurs et des reccords. Après tout un attribut n'est qu'une façon d'encapsuler un type simple : integer, string, datetime avec en plus la notion de oldvalue , newvalue et la valeur nulle évidemment ! Tous les traitements sur un attribut se feront via une liste d'attribut et plus sur l'attribut lui même.

  2. #22
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Oui moi aussi j'y vais souvent au feeling ... UML, Merise mon Q ! Au début je me laisse parfois abuser par leur méthodologie ... ah ouais ça a l'air pas mal, nouveau tout propre, pratique, structuré et puis ... mais ça va pas en fait !
    A force on finit par savoir si un truc à une chance de marcher ou au contraire de fouarrer
    De toute façon, il n'y a pas de miracle. Si une méthodologie pouvait réfléchir à notre place, on n'aurait plus de travail...
    Celà dit, UML définit qu'en même un langage de modélisation commun qui permet de faire des docs assez facilement et ainsi d'expliquer ce qu'on fait aux autres...

    Ouais des Frameworks tout fait ça existe je sais. Je ne pense pas être atteint du "not invented here syndrom" encore que Mais on consacre tellement de temps à essayer de comprendre le pourquoi du comment qu'on finit par se poser des questions : ça vaut le coup d'insister ou vaut-il mieux le développer soi même ?
    Moi en général ce qui me dérrange le plus c'est plutôt : "c'est bien ce truc, mais ça cherche à en faire 10 fois trop. Du coup j'ai plein d'effets de bords dans tous les sens, et il faut que je perdes du temps à trouver comment enlever tout ce que ce truc veux faire et dont je n'ai pas besoin".
    Ou encore : "C'est une bonne idée à la base. Mais qu'est-ce que c'est lent ! On peut pas garder un truc pareil !"

    la complexité de la recherche binaire est
    seulement O(log 2^n) .... j'utiliserais un arbre binaire de recherche en O(log n)
    C'est pas la même chose ? une recherche binaire c'est bien une recherche dichotomique non ? Avec un arbre binaire c'est exactement la même chose, sauf que les différentes branches de la recherche sont matérialisées par les branches de l'arbre.
    Maintenant si le nombre d'éléments grossit, tu devrais peut-être penser aux tableaux hash-codés ( O(1)).
    Par contre c'est beaucoup plus complexe à coder.

    Mais pour mes attributs (que j'ai finalement renommés "membres" pour le cas où je passerais sur .net) j'ai pensé à faire autrement sans objets du tout mais en utilisant des pointeurs et des reccords. Après tout un attribut n'est qu'une façon d'encapsuler un type simple : integer, string, datetime avec en plus la notion de oldvalue , newvalue et la valeur nulle évidemment ! Tous les traitements sur un attribut se feront via une liste d'attribut et plus sur l'attribut lui même.
    Ca commence curieusement à ressembler à un dataset non ?

  3. #23
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr

    Ca commence curieusement à ressembler à un dataset non ?
    Exact ! Depuis le début le framework lui même ressemble d'ailleurs furieusement à une base de données. Je considère le framework comme une sorte de point de vue différent sur les données. Il est clair que si nativement le TObjectDataset (donc fournissant des objets ou mieux une arborescence d'objets plutôt que des enregistrements) existait je l'utiliserais

    Je comprends mieux ce que tu veux dire par faire un dataset personnalisé dérivé de TDataset : effectivement j'avoue ne jamais m'y être intéressé

    Avec un arbre binaire c'est exactement la même chose,
    Arrggg autant pour moi j'ai confondu avec la hauteur de l'arbre qui est log(n) dans le meilleur des cas

  4. #24
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Idem, si je pouvais avoir le temps, j'adorerais faire un TepcPersistantDataSet, j'ai pour le moment fait une tentative en trichant via un TClientDataSet, mais cela allourdi le bouzin ...

    400 000 objets en une seconde, ouais, je ne suis jamais monté à un tel niveau, déjà tout simplement que lancer un SQL via MyDAC sur 400 000 lignes, ça bouffe énormément ! car mes objets sont toujours persistant quoi qu'il arrive ... lol, 400 000, me faut 10 minutes avec un Owner, et 11s SANS Owner (60 fois plus rapide, surement la gesiton du Name du Component ! Ouch !), mais avec la TObjectList, hum, il semble que j'ai là un travail à faire, comme ajouter une TObjectList en parallèle et ne pas utiliser le Owner, très intéressant comme travail ...

  5. #25
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bjr

    400 000 c'est juste un test de base pour me donner une idée de la charge maximale : je table donc sur 100 000 objets/seconde comme limite acceptable. Sachant que le temps de chargement depuis la base va prendre du temps : j'espère atteindre les 1000 enregs/seconde en lecture ...

    Pour les string (en tout cas sous D7) c'est clair que ça consomme des ressources : c'est géré comme des pseudo objets avec comptage de références

    Hum de 10' à 11" ça donne à réfléchir

    je n'utilise pas un TObjectList mais un IBaseObjectList écrit par mes soins mais qui en reprend le même principe à savoir la gestion en interne d'un buffer à base de pointeurs.

  6. #26
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Tu n'utilise pas le TObjectList, oh c'est dommage, il est performant, faut jouer avec Capacity, pour allouer les 400 000 cases d'un coup, ça peut accélérer les traitements (même si entre D7 et D2007, le gestion de mémoire ayant changé, FastMM, les réallocations mémoires sont nettement moins douloureuse qu'avant ... du coup beaucoup de mes algos pré-calculant les longueurs, ne sont plus valables en terme, de performance, encore une chose à améliorer avec D2009)

    Oui, la Gestion du Nom Unique (et de la Référence Unique) dans le Owner, je ne l'avais pas vu venir, je n'aurais jamais de tel volume, mais autant améliorer cela dès que possible ...

    Pour le remplissage, faudrait que je mesure via le chargement d'une collection, dès que j'ai le temps, je te donne une mesure, pour que tu puisse voir si ton 1000 enregs/seconde est optimisme ou pessimiste !

  7. #27
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Est ce que le Flyweight Pattern ne serait pas la solution au problème ?

    http://public.enst-bretagne.fr/~beugnard/cours/DP.pdf

    A la page 21 du document, il donne l'utilisation du Flyweight Pattern.
    Je me suis arrêté à ce lien parce qu'il est français, mais il y a beaucoup
    plus d'infos en anglais à ce sujet.

    C'est drôle, parce qu'après des années de programmations en delphi je suis
    arrivé aux mêmes conclusions que ce qui est dit dans cette discussion.

    Oui moi aussi j'y vais souvent au feeling ... UML, Merise mon Q ! Au début je me laisse parfois abuser par leur méthodologie ... ah ouais ça a l'air pas mal, nouveau tout propre, pratique, structuré et puis ... mais ça va pas en fait !
    A force on finit par savoir si un truc à une chance de marcher ou au contraire de fouarrer
    C'est un vrai casse tête !!!

  8. #28
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    bjr

    ShaiLeTroll

    Non je n'utilise pas la TListObject mais un équivalent quasi identique
    Comme je gère des interfaces au départ j'utilisais donc TInterfaceList que j'ai ensuite fait évoluer.

    En fait mes éléments peuvent être présent dans plusieurs listes et n'être libérés que lorsque plus aucune liste ne les références (ni aucune autre variable naturellement) Avec le reference counting ça fontionne plutôt bien.

    En plus mes listes "observent" leurs items via le pattern observer. (que j'ai adapté pour envoyer des events plutôt qu'une simple notification)


    chaplin

    merci pour le lien
    Pour les design patterns je les utilise évidemment. En fait je crois que tout le monde les utilise sans le savoir

  9. #29
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    En fait je crois que tout le monde les utilise sans le savoir
    Ca ne m'amuse pas de parler ce ces choses là en se faisant passé pour le Dr Tournesol ni pour de la frime.
    Je pense que de parler des designs patterns comme solutions à des problèmes récurrents permet de tenir
    un langage commun. Bien entendu, il faut savoir comment ça marche, mais une fois le sujet maîtrisé,
    cela permet d'avoir un meilleur recul sur les problèmes et donc un meilleurs moyen de les résoudre.

    Pourquoi utilisé le couteau à beurre pour ouvrir un huître plutôt qu'un couteau à huître.
    Les deux sont des couteaux, mais l'un sera plus adapté que l'autre.

    Mis à part, j'ose me lancé dans le débat. Je pronais le rêve d'avoir comme en C# quelque chose qui
    ressemble à un Dataset typé, mais c'est lourd. Ne pourrait on pas voir les tables d'un base de données
    au travers d'interface dont les classes en hériteraient les comportements. Pourquoi cette proposition ?
    Dans certains cas on fait une vue, qui est une jointure entre plusieurs tables, lorsque les données sont
    remontées, pour chaque type de données il pourra y avoir des méthodes (métier) liées à l'interface.
    A ce moment là, il faudrait avoir un espèce de Wizard qui génére automatiquemen une classe à partir d'une
    requête SQL pour obtenir un TDataset Typé mais de lui donné un comportement objet quand il s'agit de
    traiter un enregistrement individuellement, et le comportement d'une liste quand il faut afficher un
    ensemble d'enregistrement comme dans un DBGrid. Les applications sont fait selon un modèle objet
    tandis que les base de données fonctionnent selon une vue purement données et relations. Autrement dit,
    dans un cas on s'occupe des objets individuellement, dans l'autre cas c'est un ensemble d'enregistrement.
    En plus, avec tous ces beaux outils venant du monde UML, les beaux schémas générées par ces outils sont
    loin de la réalité des bases de données qui elles ont été créées il y a bien longtemps sans vraimant en
    respecté déjà à l'époque le modèle Merise. Donc traité un problème tordu à la base sauf s'il y a volonté
    de le détordre risque de s'empiré avec ces beaux outils.

    C'est un avis qui accepte volontié la critique.

  10. #30
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Points : 1 561
    Points
    1 561
    Par défaut
    Citation Envoyé par chaplin Voir le message
    Ca ne m'amuse pas de parler ce ces choses là en se faisant passé pour le Dr Tournesol ni pour de la frime.
    Ce que Phplive a voulu suggérer, c'est qu'un développeur avec beaucoup d'expérience et de recul en POO utilise les design pattern de façon quasi-naturelle. Il faut rappeler que le GOF n'a rien inventé, ils ont tout bonnement inventoriés les cas devant lesquels les développeurs se trouvent régulièrement confrontés en pratiquant la POO. Puis ils ont élaboré une réponse optimisée au regard des pratiques déjà utilisées.

    Comme tu l'as dit, le travail du GOF a permis de "parler un langage commun" et surtout de permettre à tout jeune développeur d'acquérir plus rapidement les bonnes pratiques.

    Par ailleurs, en ce qui concerne UML et les bases de données, je peux t'assurer que tu peux vraiment concilier les deux. En effet, j'utilise au quotidien les InstantObject, j'utilise également ModelMaker qui me permet de bâtir mon modèle UML puis d'obtenir assez simplement le modèle relationnel.
    J'utilise tout cela sur le projet sur lequel je travaille maintenant depuis plus de trois ans et je peux t'assurer que c'est fiable, robuste et surtout quel gain de temps.

  11. #31
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Ce que Phplive a voulu suggérer, c'est qu'un développeur avec beaucoup d'expérience et de recul en POO utilise les design pattern de façon quasi-naturelle
    D'accord, je prend la remarque sans aucune rancune et j'apprécie l'accueil, mais je ne pense pas qu'aux quotidiens
    tout le monde l'utilise correctement, moi y compris.

    On a parfois une facheuse tendance à faire un amalgame, pour ne pas dire mixer les design patterns. Ce que je trouve
    interessant dans les exemples qu'on trouve sur internet, c'est qu'il y a une réélle décomposition du problème.

    C'est comme faire un art martial, d'abord on apprend chaque geste séparément puis on compose au fur et à mesure pour
    éxécuter des scénarios. Je considère chaque design pattern comme un geste pour réaliser des problèmes plus complexe.
    Ne pas mettre le chariot avant les boeufs. Ce n'est pas une raison d'en faire une religion, mais ça donne de bons
    reflex.

    Comme tu le soulignes, avec beaucoup d'experience, bien entendu il faut pratiqué mais cela pourrait suggéré on
    apprend sur le tas alors que la démarche naturelle serait de voir les petits problèmes séparements pour s'occuper
    de problèmes plus complexes. Je suis convaincu que pour pas mal de gens les Gof sont une forme d'abstraction de
    la littérature informatique comme l'est UML. Quand on est dans l'ignorance, on peut la cultivée longtemps tant
    qu'on a pas vu une démonstration convaincante.

    j'utilise également ModelMaker
    A ce titre, il y avait un des auteurs qui avait écris un bouquin sur les design Pattern en allemand,
    j'ai jamais réussi à mettre la main dessus, il semblait être bien écrit.

    J'utilise tout cela sur le projet sur lequel je travaille maintenant depuis plus de trois ans et
    je peux t'assurer que c'est fiable, robuste et surtout quel gain de temps.
    Tant mieux, et je suis heureux de l'apprendre. Au moins je n'ai pas préché dans le desert

  12. #32
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bjr

    Houlà je voulais juste dire que au départ j'utilise certaines structures et que ce n'est souvent qu'après par hasard que je découvre que le principe existe déjà et qu'il s'appelle par ex un design pattern. Enfin c'est mon cas. A ce moment là je me rends compte que je ne l'utilise pas vraiment comme indiqué dans la plupart des docs mais plutôt sous une forme dérivée/adaptée. Je suppose que c'est la différence entre la théorie et la pratique

    Honnêtement je me fous bien qu'on appelle ça un pattern, un algo, une méthode, "le truc que c'est moi qui l'a inventé na !" ou autre pourvu que ça fonctionne et surtout que je comprenne comment

    Ce que Phplive a voulu suggérer, c'est qu'un développeur avec beaucoup d'expérience et de recul en POO utilise les design pattern de façon quasi-naturelle
    Exact !

    Maintenant il est vrai qu'il vaut mieux avoir une certaine rigueur et le fait de savoir que ça existe avant de se lancer dans le développement c'est un énorme avantage.


    Je suis convaincu que pour pas mal de gens les Gof sont une forme d'abstraction de
    la littérature informatique comme l'est UML
    Hélas tu as raison car les documentations te présentent souvent ces algos de façon beaucoup trop généraliste et soulèvent généralement plus de questions qu'elles n'apportent de réponses. Mon impression en lisant certaine doc : bon ok c'est bien mais comment je l'utilise en pratique ? Comment je l'adapte à mon problème donné ? En fait je pense que c'est à ce moment que l'expérience entre en jeu chose qu'aucune doc au monde ne pourra jamais fournir.


    une classe à partir d'une
    requête SQL pour obtenir un TDataset Typé mais de lui donné un comportement objet quand il s'agit de
    traiter un enregistrement individuellement, et le comportement d'une liste quand il faut afficher un
    ensemble d'enregistrement
    Oui mais le hic c'est que c'est plus un banal objet qui représente chaque enregistrement lorsque le dit Dataset est basé sur un requête SQL mettant en jeu des jointures complexes entres différentes tables. Dans ce cas on a plutôt une arborescence d'objets.

    Par ex la liste des commandes d'un fournisseur donné

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Résultat SQL
    [Fournisseur][Commande A][Article X]
    [Fournisseur][Commande A][Article Y]
    [Fournisseur][Commande B][Article W]
    [Fournisseur][Commande B][Article Y]
    [Fournisseur][Commande B][Article Z]
    [Fournisseur][Commande C][Article X]
    [Fournisseur][Commande C][Article Z]
     
     
    Arbre
     
    [Fournisseur]
    	[Commande A]
    		[Article X]
    		[Article Y]
    	[Commande B]
    		[Article W]
    		[Article Y]
    		[Article Z]
    	[Commande C]
    		[Article X]
    		[Article Z]
    Et naturellement chaque objet de l'arbre doit pouvoir être accessible individuellement et supporter le CRUD (hé voilà encore un acronyme à la noix pour Create Retrieve Update Delete )


    Sans compter avec la problèmatique suivante :

    Je veux le fournisseur et les articles pour les commandes A, B et C

    En SQL j'obtiens exactement la même chose

    Par contre niveau objet je pensais plutôt à :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [Commande A]
    	[Fournisseur]
    	[Article X]
    	[Article Y]
    [Commande B]
    	[Fournisseur]
    	[Article W]
    	[Article Y]
    	[Article Z]
    [Commande C]
    	[Fournisseur]
    	[Article X]
    	[Article Z]

    Maintenant on peut aussi considérer que le dataset fournit une liste d'objets pour chaque enregistement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Enreg[0]
    	[Fournisseur]
    	[Commande A]
    	[Article X]
    Enreg[1]
    	[Fournisseur]
    	[Commande A]
    	[Article Y]
    Enreg[2]
    	[Fournisseur]
    	[Commande B]
    	[Article W]
    Enreg[3]
    	[Fournisseur]
    	[Commande B]
    	[Article Y]
    Enreg[4]
    	[Fournisseur]
    	[Commande B]
    	[Article Z]
    Enreg[5]
    	[Fournisseur]
    	[Commande C]
    	[Article X]
    Enreg[6]
    	[Fournisseur]
    	[Commande C]
    	[Article Z]
    Tient je garde cette idée pour plus tard ...

  13. #33
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Houlà je voulais juste dire que au départ j'utilise certaines structures et que ce n'est souvent qu'après par hasard que je découvre que le principe existe déjà et qu'il s'appelle par ex un design pattern
    On est dans le débat

    Hélas tu as raison car les documentations te présentent souvent ces algos de façon beaucoup trop généraliste et soulèvent généralement plus de questions qu'elles n'apportent de réponses. Mon impression en lisant certaine doc : bon ok c'est bien mais comment je l'utilise en pratique ? Comment je l'adapte à mon problème donné ? En fait je pense que c'est à ce moment que l'expérience entre en jeu chose qu'aucune doc au monde ne pourra jamais fournir.
    Nous somme d'accord

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Enreg[0]
    	[Fournisseur]
    	[Commande A]
    	[Article X]
    Enreg[1]
    	[Fournisseur]
    	[Commande A]
    	[Article Y]
    Enreg[2]
    	[Fournisseur]
    	[Commande B]
    	[Article W]
    Enreg[3]
    	[Fournisseur]
    	[Commande B]
    	[Article Y]
    Enreg[4]
    	[Fournisseur]
    	[Commande B]
    	[Article Z]
    Enreg[5]
    	[Fournisseur]
    	[Commande C]
    	[Article X]
    Enreg[6]
    	[Fournisseur]
    	[Commande C]
    	[Article Z]
    Oui c'est tout à fait comme cela que je l'envisageait, mais pour réctifié mon propos sur le TDataset,
    ce serait davantage d'avoir une classe qui encapsule à la fois :
    - un comportement de TDataset (property) pour le publié vis à vis d'un datasource
    - et le comportement d'un objet, voir la classe de l'objet qui intégre le Dataset.

    Toute la difficulté est de trouver cette frontière entre le monde objet et le monde relationnel.
    Parfois on voudrait l'un, parfois l'autre, parfois les 2 à la fois.

    Si on affiche les données dans un DBGrid et là j'élargit mon raisonnement à tous les composants tiers qui existent sur le marché,
    il serait dommage de s'en privé.

    En revanche, lorsqu'il s'agit de s'attaquer à la partie métier, c'est vrai que la vue objet est bien plus pratique.
    Mais si on peut faire les 2 à la fois, c'est top parce que chacun a ses avantages et ses inconvénients.

    C'est pour celà que j'évoquais le Flyweight pattern, car il renvoit l'instance d'une classe. Il biaise la "vue" objet en faisant
    croire qu'il y a un objet par enregistrement. Je tiens ce raisonnement uniquement pour des raisons de performance.

    Il n'y a rien de plus emmerdant que d'écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     MyFacture.FiedByNAme('NOM_CLIENT').AsString := MyClient.FiedByNAme('NOM_CLIENT').AsString ;
    au lieu de:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     MyFacture.Nom_Client := MyClient.Nom_Client;
    c'est d'une part plus lisible et plus métier.

    Peut être que je suis à coté de la plaque

  14. #34
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    MyFacture.Nom_Client := MyClient.Nom_Client;

    Peut être que je suis à coté de la plaque
    Pas du tout c'est exactement ce que le framework se propose de faire

    Bref

    MyFacture = TMyFacture.Create();
    MyFacture.Load("000001");
    MyFacture.DateRelance := Now;
    MyFacture.PrintRelance;
    MyFacture.EmailRelance;
    MyFacture.Save;
    MyFacture.Free;

    et basta !

    Seulement voilà derrière y'a souvent un SGBDR

    Donc faut se taper le sale boulot
    Mais ça commence à prendre tournure.
    Pour la couche Model/Persistance du moins

  15. #35
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Seulement voilà derrière y'a souvent un SGBDR
    C'est la majorité des cas, sinon il y aurait beaucoup plus de SGBDOO sur le marché, lesquels sont utilisés dans des cas
    où effectivement le SGBDR ne peut pas répondre efficacement, mais combien y en a-t-il ?

    MyFacture = TMyFacture.Create();
    MyFacture.Load("000001");
    MyFacture.DateRelance := Now;
    MyFacture.PrintRelance;
    MyFacture.EmailRelance;
    MyFacture.Save;
    MyFacture.Free;
    Exactement, c'est mieux que la ribanbelle d'événements à gérer de part :

    - le TDataset
    - le TField
    - le TDatasource

    Parce qu'avec la floppée d'événements que chacun propose, avec plusieurs tables mis en jeux, ça devient une vraie usine à gaz
    bien que dans certain cas ça aide, mais à utilisé avec modération

  16. #36
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Parce qu'avec la floppée d'événements que chacun propose, avec plusieurs tables mis en jeux, ça devient une vraie usine à gaz
    C'est clair !

    Maintenant même avec des objets je suis pas sûr que ce ne soit pas aussi une petite (grosse ?) usine par contre côté facilité d'emploi c'est pas comparable ! Que du bonheur

    Côté événement ben j'ai du en ajouter un paquet

    Ma structure est globalement celle-ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    [Objet réellement persistant]
    POObject : IPOObject
    	[Liste d'attributs IAttribut]
    	FAttributeList : IAttributeList
    		[Chaque attribut est unique et associé exclusiment à 1 et 1 seul IPOObjet]
    		[Chaque attribut est nommé]
    		FAttributeList['XXX'] : IAttribut
     
    	[Facultatif propriété permettant d'accèder à chaque attribut au travers d'un type simple]
    	Property XXX : <type simple>  read GetXXX write SetXXX	
     
     
     
    [Liste d'objets métiers IBOObject de même type]
    BOObjectList : IBOObjectList
     
     
     
    [Objet métier - ce sont les seuls qu'on manipule]
    BOObject : IBOObject
    	[Référence vers 1 POObject]
    	FPOObject : IPOObject;  
    	[Facultatif -> raccourcis vers les attributs de FPOObject
    	Property XXX
     
    	[Liste contenant exclusivement des objets IBOObject ou IBOObjectList]
    	[Chaque item est nommé]
    	FMixedObjectList : IBOMixedObjectList
    		FMixedObjectList['YYY'] : IBOObjectList
    		FMixedObjectList['ZZZ'] : IBOObject
     
    	[facultatif -> raccourcis vers les objets contenus dans FBOMixedObjectList]
    	Property YYY : IBOObjectList read GetYYY
    	Property ZZZ : IBOObject read GetZZZ

  17. #37
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2004
    Messages : 17
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par chaplin Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     MyFacture.Nom_Client := MyClient.Nom_Client;
    Je dirais même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyFacture.Client := MyClient;
    Ou même puisqu'une facture appartient forcément à un client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyFacture := ObjFacture.Create(MyClient);
    Peut-être que la limitation de Delphi aujourd'hui vient justement de ce TDataset, trop proche de la base de donnée il ne permet pas vraiment de coder de véritables objets métiers.

  18. #38
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyFacture.Client := MyClient;
    A la limite, mais l'experience montre que sur une facture, il n'y a qu'une partie des informations de l'entité client,
    parce qu'on essaye d'utiliser la 3ème forme normale (pas tout le temps mais souvent) avec Merise pour éviter les redondances.

    C'est là où la programmation objet trouve ses limites. En SQL, on récupère uniquement ce qu'on a besoin, en programmation objet,
    c'est un lot de propriété au travers d'un objet.

    Je dirais que SQL est plus souple particulièrement dans l'écriture de procédure stockées. Je parle en mon nom.

    Maintenant, il existe LINQ qui offre les possibilité de SQL avec une dimension objet, car on peut créé des classes dynamiquement
    en déclarant un Var. C'est effectivement une possibilité qu'on ne trouve pas dans Delphi.

    Ce qui serait génial, c'est que le générateur SQL des composants TQUERY ou équivalents transposent sous forme objet le
    résultat de la requête comme le fait LINQ, voir même que la norme SQL propose une sortie de ces résultats sous forme objet au
    travers d'interface. D'ailleurs le SOA est une des illustrations de l'utilisation intensive des interfaces.

    Le danger, c'est de trop s'ancrer dans un modèle objet. C'est comme dire que le capitalisme et le communisme sont deux visions
    à part entière de l'économie, alors que dans la réalité on mixe les deux modèles au quotidien, du moins les deux cohabitent très bien, quand l'un merde on se rattrape
    sur l'autre et vice verca en fonction des circonstances. J'éxagère la métaphore, mais la réalité n'en est pas loin.

    La seule réponse c'est la notion d'interface, ensuite on met ce qu'on veut derrière, les bibliothèques de types en sont une bonne illustration.

    C'est pour cela que le modèle de phplive est pas mal. Encore une fois, je donne mon point de vue, je ne détiens pas la vérité

  19. #39
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bjr

    MyFacture := ObjFacture.Create(MyClient);
    Oui mais alors dans le create le client est facultatif car lorsqu'on charge une facture déjà existante on se moque bien du client : le nr de facture suffit

    je préfère de toute façon ne pas surcharger les constructeurs et l'assignation
    MyFacture.Client := MyClient; est plus pratique. On peut alors déclencher une exception si on tente de modifier le client sur une facture déjà envoyée par ex.
    Bien sûr en mode superviseur on peut tout faire mais chut !

    voilà le genre de contrôle qu'on peut facilement implémenter au travers d'un objet métier et dont la base de données n'a pas besoin d'avoir connaissance.



    limitation de Delphi aujourd'hui vient justement de ce TDataset, trop proche de la base de donnée
    Effectivement les datasets comme leur nom l'indique sont orientés données tout comme les composants DBxxxxx et certainement pas objet.

    Au travers du framework mon but est de m'affranchir des TDBxxxx quels qu'ils soient.

  20. #40
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Re

    C'est pour cela que le modèle de phplive est pas mal. Encore une fois, je donne mon point de vue, je ne détiens pas la vérité
    Hé hé merci
    Personne ne détient la vérité comme l'atteste ma signature


    A la limite, mais l'experience montre que sur une facture, il n'y a qu'une partie des informations de l'entité client,
    parce qu'on essaye d'utiliser la 3ème forme normale (pas tout le temps mais souvent) avec Merise pour éviter les redondances.

    C'est là où la programmation objet trouve ses limites. En SQL, on récupère uniquement ce qu'on a besoin, en programmation objet,
    c'est un lot de propriété au travers d'un objet.

    Ici on charge effectivement tout le client mais la facture ne conserve qu'un pointeur vers le client (vision objet) et l'ID du client (relationnel).
    Maintenant comme une facture doit pouvoir être "resortie" à l'identique même x années plus tard (alors que l'adresse du client à peut être changée) on conserve aussi certains champs du client dans la facture.
    Ici c'est lors de l'assignation qu'on met à jour les propriétés de l'objet facture en plus de l'ID client obligatoire.

    Avec des objets et une gestion du cache normalement on évite les redondances puisqu'on ne manipule que des pointeurs sous Delphi. Note qu'on peut quand même retirer un objet du cache si on y tient dans ce cas il en existera plusieurs copies

    Je dirais que SQL est plus souple particulièrement dans l'écriture de procédure stockées
    Comme quoi à un pb donné -> plusieurs visions possibles.
    perso je n'utilise pas du tout les procédures stockées. Je n'ai jamais variment compris pourquoi j'irais mettre du code dans la base. Sauf peut-être si ce code permettait à la dite base de me retouner ...des objets

Discussions similaires

  1. Remplacer caractère ' ( quote ) par "\n"
    Par Eric45 dans le forum C++
    Réponses: 3
    Dernier message: 28/11/2007, 00h56
  2. Réponses: 5
    Dernier message: 30/05/2005, 16h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo