Sommaire | ||
---|---|---|
|
C’est quoi la surcharge multiple
L'ERP Divalto permet nativement la surcharge.
C'est le terme employé pour désigner la faculté de Divalto à modifier le comportement du logiciel ou de lui ajouter des comportements via un développement sur la base de l'ERP standard.
Autrement dit, c'est la possibilité d'ajouter/modifier/supprimer des données, des traitements ou des interactions avec l'utilisateur à l’ERP sans en altérer les fonctions de base.
La surcharge multiple va permettre d'activer un mode d'exécution de l'ERP particulier, dans lequel plusieurs surcharges faites de manière indépendante vont venir s’empiler en couches, apportant ainsi les ajouts de chacune des couches de surcharge avec un minimum de travail et de développement, puisque chaque couche reste indépendante des autres couches
La surcharge multiple permet aussi d’augmenter la capacités des zones de surcharges prévu a cette effet (Zone U). Cette capacité de surcharge multiple est dite ‘multiple’ même dans une situation de non multiplicités des couches, par exemple en apportant une couche unique de verticalisation ou localisation.
Pourquoi mettre en œuvre la surcharge multiple
La surcharge multiple apporte un gain de temps et d'efficacité lorsque des surcharges déjà existantes sont requises pour répondre aux besoins d'utilisation ERP d'un client.
Il devient possible de réutiliser des couches de surcharge, et d’en empiler plusieurs, Sans forcément avoir la maîtrise totale d'une couche intermédiaire. On peut donc imaginer utiliser une couche de surcharge développée par quelqu'un d'autre dans un autre contexte client.
Exemple fictif de surcharge multiple
L'ensemble des exemples qui vont suivre sont basés sur le cas suivant (cas fictifs, aucune ressemblance avec des entreprises existantes)
Surcharge A : Maroquinerie
Prenons une entreprise d’un métier particulier comme la Maroquinerie.
Ce métier nécessite de marquer les articles qui sont en cuir, afin d’imprimer un texte spécifique aux articles en cuir sur les pièces commerciales.
Un développement spécifique peut donc être fait dans un esprit de “verticalisation de l’ERP à un métier”, avec ajout de champs dans les écrans et modification de traitement d’impression.
Une entreprise du métier de la maroquinerie peut utiliser cette surcharge pour répondre à ses besoins
Surcharge B : Italie
Prenons une entreprise qui a une agence en Italie.
Cette localité nécessite d’appliquer des règles locales, notamment une localisation AOP qui interdit de vendre des produits hors Italie, et cette restriction doit apparaitre sur les pièces commerciales.
Un développement spécifique peut donc être fait dans un esprit de “localisation ERP à un pays”, avec ajout de champs dans les écrans et modification de traitement d’impression
Une entreprise du métier de la maroquinerie peut utiliser cette surcharge pour répondre à ses besoins
Surcharge finale : le cas Borsetta
L’entreprise Borsetta est une entreprise de maroquinerie italienne
Pour répondre a ses besoins, il y a 2 possibilités principales:
inventer une nouvelle couche de surcharge Borsetta en copiant les spécificités de la maroquinerie et de l’Italie, et si besoin y adjoindre de spécificités client ; toutes les surcharges se trouvent donc mélangées
utiliser la surcharge multiple pour empiler les couches Maroquinerie et Italie, et si besoin y adjoindre une couche spécifique client ; chaque couche reste autonome, et peut évoluer de manière séparée
Astuce |
---|
C’est donc ici que la surcharge multiple apporte des réponses techniques qui permettent de faciliter, accélérer et sécuriser les développements de spécifiques, en séparant des couches qui restent autonome |
Le gros avantage est la maintenance des couches, car une couche comme la Maroquinerie pourra évoluer pour apporter plus de fonctionnalités, ou corriger des anomalies, et venir s’insérer sans que les autres couches ne nécessitent de modification
(Attention, il y a des restrictions possibles, comme par exemple le nommage des champs qui doivent rester avec des nom différents dans toutes les couches)
Surcharge finale en mode surcharge multiple Borsetta
On choisit de répondre aux besoins Borsetta par la surcharge multiple. Cela implique
que les couches qui entrent dans un empilement de surcharges vont devenir des ADD-ON
que l’on crée une couche pour porter les spécificités du client et les adaptations de l’empilement des couches
La surcharge multiple fonctionne en cloud, permettant même l’utilisation de couches provenant d’un autre auteur de surcharge. Les add-on sont alors en lecture seule via des chemins cloud
Les recommandation de développement pour faciliter la surcharge multiple
Pour que les couches de surcharge multiple s’imbriquent au mieux, il y a quelques consignes lors du développement des couches
Les surcharge de TT ou TM
lors de l'écriture de surcharge d’un fonction/procédure standard xxx , il faut mettre l’appel à standard.xxx à l’intérieur. C’est ainsi que les couches vont pouvoir s’empiler naturellement
tout code spécifique doit être externalisé dans un module de type TM ou TT à part, avec uniquement un appel a une fonction depuis la fonction/procédure standard xxx. Ceci afin de pouvoir agir lors de l’empilement des couches sans casser la surcharge xxx
Exemple
Bloc de code |
---|
SURCHARGE GTUMPCE : CODE DE DEPART Procedure Piece_Imp_Ligne_Read_ap ; beginp If SOC.MaroImprCuirFl = OUI and ART.MaroCuirFl = OUI G4.Lib(2) = SOC.MaroImprCuirTxt XMiPrint (MZ.MICLE, 19) Else G4.Lib(2) = "Il est en cuir" XMiPrint (MZ.MICLE, 19) EndIf endp |
CE QUI NE VA PAS
Il n’y a pas d’appel a standard.Piece_Imp_Ligne_Read_ap ! Cela va donc bloquer l’empilement des couches
Le code est directement dans la fonction/procedure de surcharge
CE QU’IL FAUT CHANGER
créer un module de type TM ou TT séparé, qui contient le code spécifique à la surcharge
appeler le standard.
appeler la fonction spé
Bloc de code |
---|
MODULE DEDIE : MAROTMPCE Procedure AjoutTexteMaroquinerie beginp If SOC.MaroImprCuirFl = OUI and ART.MaroCuirFl = OUI G4.Lib(2) = SOC.MaroImprCuirTxt XMiPrint (MZ.MICLE, 19) Else G4.Lib(2) = "Il est en cuir" XMiPrint (MZ.MICLE, 19) EndIf endp |
Bloc de code |
---|
SURCHARGE GTUMPCE : CODE D'ARRIVEE Procedure Piece_Imp_Ligne_Read_ap ; beginp ;en surcharge on appelle par défaut la couche supérieure standard.Piece_Imp_Ligne_Read_ap ;mon code spé est dans un module séparé maropmpce.AjoutTexteMaroquinerie endp |
Les dictionnaires
Les dictionnaires des couches add-ons seront rangés dans des sous-dossier du fhsql.
Ceci afin d'éviter les conflits de nommage : le dictionnaire GTFDD va exister dans chaque couche, et il ne peut être renommé ; il faut donc les ranger dans des sous-dossiers.
Il et recommandé de donner aux sous-dossiers le même nom que l’add-on
Les éléments techniques en surcharge multiple
Le fichier OVERWRITE.TXT
Le fichier nommé OVERWRITE.TXT a les caractéristiques suivantes
est un fichier texte simple (encodage à éviter : UTF-8-BOM), éditable avec un bloc-notes ou XWIN
sa présence dans les implicites active le mode surcharge multiple lors de l’exécution des programmes Diva ERP
sert de référence pour la synchronisation des dictionnaires (mise à jour du schéma de base de données)
doit indiquer les différentes couches (3 dans notre exemple) et l’ordre d’empilement (selon ordre d’apparition dans le fichier), en indiquant la couche finale et les couches add-on
permet de donner les chemins vers les autres couches (en absolu ou relatif)
N’a pas besoin d’exister dans TOUTES les couches qui sont empilées, chaque couche détermine s’il est nécessaire d’en avoir ou pas ( débordement de la zone U par exemple ), les contenus seront bien sur différents couche par couche
doit être placé dans les IMPLICITES dans le dossier FICHIERS pour le cloud mais peut être à la racine des spécifiques en Onprem en ajoutant le chemin dans les implicites
une synchronisation de dictionnaire vie XPSql doit trouver ce fichier pour gérer la fusion des dictionnaires de chaque couche
Info |
---|
En plus d’activer le mode surcharge multiple, ce fichier déclenche la capacité des dictionnaires DHSD à étendre la zone U au-delà de la limite de taille définie dans ce dictionnaire. C’est une caractéristique importante et essentielle pour permettre aux couches de se compléter les unes aux autres sans risque de débordement ou chevauchement |
Remarque |
---|
Attention, l’ordre logique des add-on figurant dans le fichier OVERWRITE doit être identique à l’ordre logique utilisé dans les implicites. Cela implique au niveau technique que l’ordre des lignes de texte du fichier OVERWRITE est l’INVERSE de l’ordre des lignes du texte du fichier IMPLICITE (car l’implicite doit fournir la couche la plus spécifique en premier dans la recherche des chemins, alors que l’overwrite doit fournir les couches successives de dictionnaires en partant de la moins spécifique) |
Exemple de fichier Overwrite.txt pour la couche FINALE
Bloc de code |
---|
;dans borsetta on se considère comme dernier niveau, donc addon=0 false, et les autres comme ajouts donc addon=1 true ;addon italie, en ABSOLUTE PATH <Type>OBJECT<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/objets <Type>SOURCE<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/sources ;addon maroquinerie, en ABSOLUTE PATH <Type>OBJECT<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/objets <Type>SOURCE<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/sources ;niveau client borsetta : en PATH <Type>OBJECT<addon>0<name>borsetta<path>objets <Type>SOURCE<addon>0<name>borsetta<path>sources |
On peut voir dans cet exemple les règles de construction:
un
;
indique une ligne de commentaireon place les ADD-ON en premier, en mettant “true” sous la forme :
<addon>1
on place la couche finale en dernier, en mettant “false” sous la forme :
<addon>0
chaque couche doit être nommée avec la balise
<name>
, avec un nom simple court, sans caractères spéciaux ni espace, mais qui synthétise la fonction de la couche, ici par exemple<name>italie
ou<name>maroquinerie
chaque ligne est typée avec les balises
<Type>OBJECT
pour un chemin de type objets diva, ou<Type>SOURCE
pour un chemin de type sources divachaque ligne a pour but d’indiquer un chemin
la balise
<absolutepath>
indique un chemin absolu. C'est le cas à utiliser pour les lignes ADD-ON pour ‘sortir' des implicites de la couche courantela balise
<path>
indique un chemin relatif. C'est le cas à utiliser pour ‘rester’ dans la couche courante
lorsqu’on utilise un chemin relatif avec
<path>
il ne faut PAS démarrer par un/
car le dossier indiqué est forcément au noeud de départ
Exemple de fichier Overwrite.txt pour la couche MAROQUINERIE
En cloud, les chemins sont obligatoirement en absolutepath.
En OnPremise les deux sont possibles
Bloc de code |
---|
;dans la maroquinerie on se considère comme dernier niveau puisqu'on ne connait ni italie ni borsetta, donc addon=0 <Type>OBJECT<addon>0<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/objets <Type>SOURCE<addon>0<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/sources |
Remarque |
---|
Attention, les fichiers Overxwrite.txt à manipuler sont exclusivement ceux qui sont dans les implicites de chaque couche de surcharge. Un exemplaire est également présent dans le dossier de gestion de la base de données (avec le FHSQL et les dictionnaires) mais celui-ci ne doit pas être modifié manuellement Il est placé ici lors de la synchronisation des dictionnaires. |
Si la couche add-on veut gérer un mécanisme de HOTFIX, il convient d’ajouter les chemins de HOTFIX dans le groupe de chaque add-on, et plaçant le hotfix avant son propre standard
Exemple : Italie et Maroquinerie ont des Hotfix
Bloc de code |
---|
<Type>OBJECT<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/HotfixA/objets <Type>SOURCE<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/HotfixA/sources <Type>OBJECT<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/objets <Type>SOURCE<addon>1<name>italie<absolutepath>/surcharge/italie_erp220/sources <Type>OBJECT<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/HotFix1/objets <Type>SOURCE<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/HotFix1/sources <Type>OBJECT<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/objets <Type>SOURCE<addon>1<name>maroquinerie<absolutepath>/surcharge/maroquinerie_erp220/sources <Type>OBJECT<addon>0<name>borsetta<path>/objets <Type>SOURCE<addon>0<name>borsetta<path>/sources |
Les implicites
Le fichier des implicites de la couche finale doit décrire tous les chemins nécessaires de chaque couche. Comme indiqué précédemment, l’ordre dans ce fichier doit être l’inverse de celui du fichier Overwrite.
Remarque |
---|
Au sein d’une même couche, des noms d’objets identiques sont nécessairement dans des dossiers différents, et une hiérarchie via l’implicite. C’est ce qui permet d’avoir par exemple plusieurs hotfix dans une même couche (un objet placé en premier remplace les suivants) Sur un ensemble de couches, les noms d’objets différents entrent dans le mécanisme de surcharge multiple Ainsi un objet d’une couche sera imbriqué avec le même nom d’objet d’une autre couche (un objets placé en premier sera imbriqué en première position) |
Exemple :
Couche Italie : un GTUMPCE correctif et un GTUMPCE d’origine
Couche Maroquinerie : un GTUMPCE d’origine
Couche Borsetta : un GTUMPCE correctif et un GTUMPCE d’origine
Lors de l’appel à GTTMPCE se déclenche l’imbrication des GTUMPCE. Le premier chemin dans l’implicite devra être le premier de chaque couche, donc dans l'exemple Hotfix Borsetta, puis Borsetta, puis Maroquinerie, puis Hotfix italie, puis Italie
Dans notre cas on aura donc d’abord la couche finale, puis la couche italie et maroquinerie.
Bloc de code |
---|
;en premier on met la couche client finale, avec les chemins, le fichier Overwrite doit être présent /surcharge/borsetta_erp220 /surcharge/borsetta_erp220/objets /surcharge/borsetta_erp220/sources /surcharge/borsetta_erp220/fichiers ;ensuite on met les add-on /surcharge/italie_erp220/sources /surcharge/italie_erp220/objets /surcharge/italie_erp220/fichiers /surcharge/maroquinerie_erp220/objets /surcharge/maroquinerie_erp220/sources /surcharge/maroquinerie_erp220/fichiers /divalto/erp220/sources /divalto/erp220/objets |
Les éléments de surcharge
Nom de l'élément | Partie de l'élément | Comportement en surcharge multiple (si le même élément existe dans plusieurs couches) | Actions à faire |
---|---|---|---|
Dictionnaire .DHSD | Champ U dans un dictionnaire standard Table U dans un dictionnaire standard | Les champs de chaque couche vont s’ajouter. Attention il ne doit pas y avoir de conflit de nom de champ entre couches | (aucune, la fusion pour le schéma et la compilation vont se faire naturellement) |
Dictionnaire .DHSD | Table ou champ dans un dictionnaire add-on | ||
Source .DHSP | Source de type TT/TZ | Le TT de chaque couche va être appelé successivement, à condition que le STANDARD.xxx n’est pas été oublié ou remplacé. S’il n’y a pas d’appel à standard. la chaîne s’arrête | S’assurer de la présence du standard.xxx si on veut enchaîner les couches, ou ne pas en avoir si on ne veut pas empiler |
Source .DHSP | Source de type TM | ||
Source .DHSP | Source de type xxTMFICSQL | Les xxTMFICSQL ne sont pas des surcharges, il n’y a donc pas d’empilement de couches | Fusionner à la main les couches |
Masque écran .DHSF | Ecrans EE/EZ | Il n’y a pas de fusion des écrans ! | Recréer un masque d’écran, et reporter manuellement les éléments |
Masque écran .DHSF | Traitements EE/EZ | il n’y a pas de fusion des traitements écrans ! | |
Masque imprimante .DHSI | Bloc impressions II | Il n’y a pas de fusion des blocs ! | Recréer un masque d’écran, et reporter manuellement les éléments |
Masque imprimante .DHSI | Traitements II | il n’y a pas de fusions des traitements d’impressions ! | |
Menus .DHFI | Surcharge de menu IA | Il n’y a pas de fusion des fichiers .DHFI! donc pas de fusion des menus | Reporter dans la couche finale les ajouts de chaque couche |
Styles .DHFI | Surcharge de feuille de style | Il n’y a pas de fusion des fichiers .DHFI! donc pas de fusion des feuilles de style | Reporter dans la couche finale les ajouts de chaque couche |
RecordSql .DHSQ | La fusion des recordSql compilés .DHOQ se fait naturellement. Les champs et tables de couches inférieurs sont automatiquement remontées dans la couche finale | ||
Jointures .DHSJ | Les jointures de chaque couche vont s’ajouter. Attention il ne doit pas y avoir de conflit de nom de champ entre couches |
Pour plus de détails et d’illustration, suivez le guide pas à pas plus bas.
Compléments concernant les sources/objet/surcharge pour le cas des masques écran/imprimante
Lorsqu’une couche modifie par exemple un masque écran ou impression (donc un élément qui ne se fusionne pas dans le tableau ci-dessus), et que les autres couches n'ont pas de modification de ce même écran, il n’y a aucune intervention à faire. La modification d’une couche inférieur sera vue et traitée naturellement, sans avoir besoin de créer un source ou compiler un objet dans la couche finale. Exemple : si la couche Maroquinerie modifie le zoom Client, mais que la couche Italie et Borsetta n’ont pas de modification de ce même zoom, alors on obtient bien un zoom, exécuté dans la couche finale, qui comporte les modifications Maroquinerie. Ce n’est que lorsque le même élément existe dans plusieurs couches que la fusion doit être faite manuellement pour les masque écran ou impression
Compléments concernant les xxTMFICSQL
Les modules xxTMFICSQL n'étant pas des surcharges, ils ne sont pas naturellement empilés s’il en existe dans plusieurs couches qui utilisent un xxPMFICSQL.
Il est donc indispensable de fusionner le code manuellement.
Pour cela il faut déclarer les modules issus des autres couches sous la forme
Module NomDeLAddOn.xxTMFICSQL.dhop as NomDeLAddOn_AddOn
Exemple
Bloc de code |
---|
Module italie.GTTMFICSQL.dhop as italie_addon Module maroquinerie.GTTMFICSQL.dhop as maroquinerie_addon Public Procedure Dossier_Select_Ap (&Dossier) RecordSql 'gtrsdos.dhoq' Dossier Dossier beginp italie_addon.Dossier_Select_Ap (Dossier) maroquinerie_addon.Dossier_Select_Ap (Dossier) endp |
De cette manière, la couche finale détermine si les procédures des autres couches sont appelées ou non, et dans quel ordre
Compléments concernant l’empilement des couches
La couche de référence est la couche client final. Tout code de surcharge existant dans cette couche sera exécuté. La surcharge multiple, en cas d’absence de surcharge sur une ouverture, ira remonter selon les implicites pour chercher la surcharge sur cette même ouverture dans les autres couches, ce qui donne l’effet principal de la surcharge multiple, à savoir qu’une couche ‘add-on’ modifie le comportement de la couche client sans que cette dernière n’ait à implémenter de modification
Exemple : une ouverture Article_update_av existe, et appelée par le standard. Si une couche ‘add-on’ implémente cette fonction (et pas la couche client) dans un objet trouvé dans les implicites, elle sera exécutée.
Mais si la couche client, ou une couche add-on, implémente une fonction il faut tenir compte des autres couches potentielles.
C’est pourquoi il est recommandé, dans toute surcharge d’une ouverture, de toujours faire appel au standard. de cette même ouverture pour continuer la propagation aux autres couches
Exemple : une surcharge de Article_update_av est fait dans un couche Italie. Elle doit faire appel à standard.Article_update_av pour permettre à la couche Maroquinerie d'être appelée
La couche client peut donc, via la méthode d'écriture, décider de la manière d’empiler les couches
soit en mettant son propre comportement, sans appeler les autres couches
soit en appelant le standard.xxx pour un empilement naturel des couches
soit en appelant explicitement une couche. Pour cela une déclaration
Exemples
Bloc de code |
---|
;=== CAS FORCE : la couche client impose un comportement Procedure Article_update_av beginP ;je fais ce qui est attendu, sans appeler les autres couches ;la simple existance de la procédure, sans appeler les autres couches, va ignorer les autres couches endP ;===CAS STANDARD : la couche laisse l'empilement 'naturel' Procedure Article_update_av beginP ;appel au standard. pour empiler les couches standard.Article_update_av ;suivi du code spécifique ;(s'il n'y a pas de code spécifique, autant ne pas déclarer la procédure) monModule.monArticle_update_av endP ;===CAS EXPLICITE : la couche décide de l'empilement Module italie.GTTMFICSQL.dhop as italie_addon Module maroquinerie.GTTMFICSQL.dhop as maroquinerie_addon Procedure Article_update_av beginP ;appel explicite (ceci est un exemple où une condition dirait si on a un comportement propre ou non if maCondition maroquinerie_addon.Article_update_av italie_addon.Article_update_av else monModule.monArticle_update_av endif endP |
Le fichier DHOS
Le fichier .DHOS a les caractéristiques suivantes:
c’est un fichier issu d’une compilation par XWIN, il n’est en aucun cas modifiable par un autre outil
il porte la combinaison des dictionnaires de données (obtenus par fusion des différentes couches ; il contient donc les positions réelles des champs des tables mémoire et SQL)
il doit être généré dans la couche FINALE
est utilisé uniquement lors de l’exécution des programmes Diva en surcharge multiple afin de fournir un dictionnaire combiné (par la couche runtime ; pas d’impact sur la synchronisation des dictionnaires)
il faut le régénérer à CHAQUE modification de l’un des dictionnaires de l’une des couches de surcharge (quel que soit le module GT,CC,…, la nature de modification de dictionnaire, quelle que soit la couche)
il faut le régénérer à CHAQUE modification du fichier Overwrite.txt
Ce fichier est obtenu par XWIN, sur le projet de la couche finale qui regroupe les surcharges, dans le menu clic-droit sur le projet puis “Compiler les dictionnaires de données (surcharges multiples)
A noter que le menu “Contrôler les fonctions” est une aide avant compilation pour détecter d’éventuels conflits de noms de fonctions/procédures entre les couches
Synchronisation des dictionnaires
Lors de la phase de synchronisation, XP-SQL doit trouver tous les dictionnaires, plus précisément celui de la couche client, et toutes les couches existantes. Comme le nom du dictionnaire est identique (par exemple GTFDDU) quelle que soit la couche, il est nécessaire d’utiliser des sous-dossiers.
La recommandation pour la structure est la suivantes:
Créer un dossier “SYNCHRO-MULTIPLE”
Placer le fichier OVERWRITE.TXT de la couche client à la racine de ce dossier
Placer les dictionnaires de surcharge de la couche client à la racine de ce dossier
Créer un sous-dossier pour chaque couche
Exemple : un dossier ITALIE et un dossier MAROQUINERIE
Placer les dictionnaires de surcharge de la couche dans son dossier
Lancer XP SQL, et choisir le dossier de synchro
Illustration
en vidéosde la surcharge multiple (vidéos et code source)
Voici quelques vidéos basées sur l’exemple fictif, à savoir un client BORSETTA maroquinier italien qui utiliser deux couches, l’une pour les spécificité Italie, l’autre pour les spécificités Maroquinerie.
Le but de ces vidéos est de présenter l’exemple dans un mode opérationnel, mais à but pédagogique.
Vidéo 1 : Introduction
Présentation de l’exemple fictif
Vidéo 2 : La couche Italie
Présentation du code Diva qui constitue la couche Italie (add-on, couche intermédiaire)
Vidéo 3 : La couche Maroquinerie
Présentation du code Diva qui constitue la couche Maroquinerie (add-on, couche intermédiaire)
Vidéo 4 : La couche Borsetta
Présentation du code Diva qui constitue la couche Borsetta (couche finale client)
Vidéo 5 : Exécution dans la couche Borsetta
Exécution de l’ERP dans la couche Borsetta, avec explications rapides sur les traversées des couches
Code source exemple fictif
Voici un zip contenant l’exemple illustré dans les vidéos
View file | ||
---|---|---|
|