Composant – Présentation générale

Composant – Présentation générale

🎯 Présentation générale

AComposant est une classe abstraite représentant un composant métier structuré. Elle implémente l’interface IComposant et hérite de AVue. Cette classe centralise la gestion des modules : Base, Achat, Main-d’œuvre, Vente et potentiellement d’autres, comme Documentation.

🔧 Composants associés

  • Base : Quantité, poids, sous-traitance (classe MComposantBase)
  • Achat : Prix unitaire et total (classe MComposantAchat)
  • Main-d’œuvre : Heures, taux horaire, globalité (classe MComposantMainOeuvre)
  • Vente : Marges, prix de vente total (classe MComposantVente)
  • Documentation : (à venir, architecture prête à l’accueillir)

🛠️ Sérialisation

Chaque sous-module est sérialisé individuellement via GetData(), ce qui permet une gestion fine des états.

Exemple de structure de données manipulée via FComposantData :

{
  m_sModele: "MonComposantExemple",
  m_sData: "{...}",                   // Données de base
  m_sDataAchat: "{...}",              // Achat
  m_sDataMainOeuvre: "{...}",         // Main-d'œuvre
  m_sDataVente: "{...}",              // Vente
  m_bModificationParUtilisateur: true,
  m_coGroupeVisible: "BASE+ACHAT+VENTE"
}

🏭 Fabrique (FComposant)

La fabrique crée ou modifie des instances de composant à partir d’une instance de FComposantData. Cela isole totalement la logique de création de composants de leur usage métier.

  • Creer(coGroupeVisible) : Ouvre un écran de sélection et renvoie un composant.
  • Modifier(sModele, sData) : Charge un composant en édition.
  • GetModele(FComposantData) : Point d’entrée principal basé sur la structure complète.

🤝 Collaboration avec COL_LambiqueShared et collections spécifiques

Chaque composant expose une méthode GetModele à travers sa propre collection de procédures spécifiques, telles que COL_LambiqueXXX. Ces collections permettent de créer dynamiquement le bon type de composant en fonction des données et de gérer les interactions avec le système dans des modules séparés.

La méthode GetModele dans chaque collection spécifique (par exemple, COL_LambiqueBox.GetModele) redirige vers COL_LambiqueShared.GetModele afin d’assurer que le code est exécuté au bon endroit, c’est-à-dire à l’intérieur du bon composant.

Voici un exemple de la méthode GetModele dans COL_LambiqueBox :

PROCÉDURE GetModele(pclData est un objet dynamique)

RENVOYER COL_LambiqueShared.GetModele(pclData)

Bien que le code soit identique dans chaque collection, cette approche garantit que l’exécution de COL_LambiqueShared.GetModele se fait dans le contexte spécifique du composant actuel, assurant ainsi une séparation claire entre la logique métier et la logique d’interface.

💡 Interface IComposant

Tous les composants hérités de AComposant doivent implémenter :

  • p_sNomComplet : chaîne
  • m_pclBase : MComposantBase
  • m_pclAchat : MComposantAchat
  • m_pclMainOeuvre : MComposantMainOeuvre
  • m_pclVente : MComposantVente
  • GetData(), SetData(sData)

🔑 Groupes de champs visibles

Le paramètre coGroupeVisible (type COVChampGroupe) permet de limiter les sections affichées (Base, Achat, Vente, etc.).

🧩 Extensibilité

Grâce à la structure FComposantData et la méthode SetData, le système est ouvert à l’ajout de nouveaux modules (ex. : m_sDataDocumentation) sans altérer la logique existante.

⚙️ Gestion des données typées dans la fabrique de composants

Lors de l’utilisation de la méthode COL_LambiqueShared.GetModele(pclData), un problème peut survenir si l’objet pclData est passé sous forme de objet dynamique non typé. WinDev ne reconnaît alors pas ses membres spécifiques.

Important :
Pour garantir un typage correct et l’accès complet aux membres de la classe FComposantData, il est recommandé de projeter manuellement l’objet dynamique dans un objet local typé à l’aide de l’affectation structurée <=.

Exemple de code correct

pclDataLocal est un FComposantData dynamique
pclDataLocal = new FComposantData
pclDataLocal <= pclData

Cette méthode permet :

  • De forcer la conversion vers le type attendu (FComposantData).
  • D’avoir accès à toutes les méthodes et propriétés spécifiques.
  • D’éviter les erreurs silencieuses typiques de l’interopérabilité entre modules ou collections.
Bonnes pratiques WinDev : Utiliser une projection explicite dans un objet local typé dès qu’un objet dynamique est passé depuis une collection, une DLL ou une procédure partagée.

Pourquoi cette étape est nécessaire

Lorsque pclData est transmis via une collection ou une procédure, WinDev perd souvent le typage réel et le traite comme un objet générique. Sans typage explicite, les méthodes comme SetData ou les champs tels que m_sDataVente peuvent ne pas être accessibles.