Bonjour,
Cette discussion tombe plutôt bien quand on se pose les questions intimes : Faut-il se mettre à Qt et se coltiner progressivement des héritages de QObjet partout? Comment obtenir un type "souple" pour les algorithmes qui en ont besoin? Comment faire communiquer différentes bibliothèques sans être trop intrusif?
Il me semble néfaste de voir pulluler les héritages vers un objet Dieu. La seule exception est celui de java : Il est standard, on ne risque pas de vouloir s'en séparer un jour xD. Par contre, on peut souhaiter continuer à faire du C++ si Qt devient obsolète ou de Dot Net si on découvre Qt :aie:
Par contre, comment obtenir la même généricité que ces objets? Pour ma part, il me manque souvent un objet de transfert dont je ne puisse connaitre le type qu'a l'exécution.
Par exemple, on peut avoir besoin de prendre en entrée un "tableau de points du plan". On veut un "x", un "y" que l'on puisse transformer en double. Savoir si ces points sont des "point2f", des "TPoint<double>", cela ne me regarde pas. Je veux un tableau d'objet possédant des propriétés "x" et "y" de type numérique sur lesquelles je puisse appeler "toDouble" en toute sérénité.
Pour mettre en place ceci, on se cogne un tas de contrôles, un tas de conversions, la création d'un nouveau type générique ( une union? une structure locale de classe? un void* et un identifiant? un boost::any? un boost::variant? )
On lit les champs d'une base de données, ben tiens, j'ai rien de mieux qu'un identifiant de type parmi 1000 prédéfinis... Et nous voila reparti pour les contrôles et la mise en place d'un nouveau variant...
On écrit un point dans une base de données, vaillant, on l'écrit en direct... On écrit ce même point dans un fichier; on met en place une sérialisation; on utilise une bibliothèque externe travaillant sur le point, on ré-introduit une abstraction,...
En somme, on finit par multiplier les conversions, et se rendre compte que ce qu'il manque, c'est un format d'échange pour les objets que l'on manipule et un poil de généricité.
On repense à java où l'on pouvait passé Objet en paramètre et appeler instanceof. On regarde un peu plus près java.lang tient Objet et Class... On voit qu'en cherchant bien, il doit être possible de lister les éléments de Class...
On plonge un peu dans Qt, on voit qu'ils ont un monstre pour la communication QObjet.
On plonge un peu dans dot net : tiens un Objet...
Comme l'objet dieu est un anti-pattern au même titre que le copier/coller, j'ai pour ma part envie de prendre la voix d'un troisième : La réinvention de la roue ( ronde quand même! ). L'idée est d'introduire les composants suivant, sur lesquels j'exerce en maître un contrôle ( i.e. loin de nokia, loin de microsoft,... )
- un variant, type QVariant, mais beaucoup plus limité aux besoins métiers
-> stockage de types de bases c++ et quelques classes métiers ( image, géométrie, ... ), à base de boost::any.
-> récupération du type du variant ( avec énumération sur la classe variant )
-> conversion du variant, vers un type concret, avec contrôle par retour d'un booléen
- Un tableau de variants :
-> encapsulation de std::vector< MonVariant >, ou équivalent, et l'interface associée
- Un objet à base de variant ( type DTO )
-> une encapsulation de std::map< std::string, MonVariant > et l'interface associée
A vrai dire, j'ai du mal à trouver mon bonheur dans l'existant. Les composants boost ( variant et any, avec any_cast et lexical_cast ) sont plutôt merveilleux. Seulement, je les trouve d'un peu trop bas niveau. Aussi, le fait de lever une exception pour connaître le type "réel" de "any", où lorsqu'un "lexical_cast" ne passe pas, me déplait.
QVariant est plutôt "dans mes goût" au niveau de l'utilisation directe de Qt, toutefois, il est pas forcément souhaitable de travailler sur des QImage dans les couches métiers...
Après, j'avoue avoir baigner beaucoup dans des univers javaïsés, mais je trouve dommage qu'il y ait un tel gap entre le void* et le QObjet ou l'Objet de dot net ( c++/cli )...
L'objet générique, non pas en temps qu'objet dieu dont toutes classes héritent; mais en temps qu'état, me semble aussi important pour faire communiquer différentes "couches" logicielles; qu'un format d'échange pour faire communiquer différents logiciels.
Ne faut-il pas un entre deux? Un/des composant(s) d'échange entre les couches métiers, avec les bibliothèques, les frameworks?
A vous les experts :mrgreen:
Puissiez-vous m'aider à trancher dans mon dilemme : Ce variant et cet Objet tu introduiras; ou pas...
ps : désolé pour le pavé