L'architecture hexagonale (Ports and Adapters) est un modèle de conception qui vise à créer des applications extensibles et maintenables en séparant clairement la logique métier des détails techniques et des dépendances externes.
Ce modèle de conception est tout à fait transposable dans le langage Progress OpenEdge ABL afin d’en tirer les mêmes bénéfices (maintenabilité et capacité d’évolution), démontrant une fois de plus la capacité de cette plateforme à s’adapter aux besoins du moment.
L'idée centrale de l'architecture hexagonale est de placer le domaine métier au centre de l'application et d'entourer cette logique métier avec des interfaces et des adaptateurs qui connectent l'application à des technologies externes (comme les bases de données, les systèmes de fichiers, les API externes, etc.).
Fichier: Customer.cls
CLASS Customer:
DEFINE PRIVATE VARIABLE customerId AS CHARACTER NO-UNDO.
DEFINE PRIVATE VARIABLE name AS CHARACTER NO-UNDO.
DEFINE PRIVATE VARIABLE email AS CHARACTER NO-UNDO.
CONSTRUCTOR PUBLIC Customer
(cid AS CHARACTER, cname AS CHARACTER, cemail AS CHARACTER):
customerId = cid.
Name =name.
email = cemail.
END CONSTRUCTOR.
METHOD PUBLIC CHARACTER getCustomerId():
RETURN customerId.
END METHOD.
METHOD PUBLIC CHARACTER getName():
RETURN name.
END METHOD.
METHOD PUBLIC CHARACTER getEmail():
RETURN email.
END METHOD.
END CLASS.
Fichier: CustomerService.cls
USING Progress.Lang.*.
INTERFACE CustomerRepository:
METHOD PUBLIC VOID addCustomer(INPUT customer AS Customer).
METHOD PUBLIC Customer getCustomerById(INPUT customerId AS CHARACTER).
END INTERFACE.
CLASS CustomerService:
DEFINE PRIVATE VARIABLE repository AS CustomerRepository NO-UNDO.
CONSTRUCTOR PUBLIC CustomerService(INPUT repo AS CustomerRepository):
repository = repo.
END CONSTRUCTOR.
METHOD PUBLIC VOID registerCustomer
(customerId AS CHARACTER, name AS CHARACTER, email AS CHARACTER):
DEFINE VARIABLE customer AS Customer NO-UNDO.
customer = NEW Customer(customerId, name, email).
repository:addCustomer(customer).
END METHOD.
METHOD PUBLIC Customer findCustomerById(INPUT customerId AS CHARACTER):
RETURN repository:getCustomerById(customerId).
END METHOD.
END CLASS.
Fichier: CustomerRepositoryImpl.cls
USING Progress.Lang.*.
CLASS CustomerRepositoryImpl IMPLEMENTS CustomerRepository:
DEFINE PRIVATE TEMP-TABLE ttCustomer NO-UNDO:
FIELD customerId AS CHARACTER. FIELD name AS CHARACTER.
FIELD email AS CHARACTER.
END.
METHOD PUBLIC VOID addCustomer(INPUT customer AS Customer):
CREATE ttCustomer.
ASSIGN
ttCustomer.customerId = customer:getCustomerId()
ttCustomer.name = customer:getName()
ttCustomer.email = customer:getEmail().
END METHOD.
METHOD PUBLIC Customer getCustomerById(INPUT customerId AS CHARACTER):
FIND FIRST ttCustomer WHERE ttCustomer.customerId = customerId NO-LOCK
NO-ERROR.
IF AVAILABLE ttCustomer THEN
RETURN NEW Customer(ttCustomer.customerId, ttCustomer.name, ttCustomer.email).
ELSE
RETURN ?.
END METHOD.
END CLASS.
Fichier: Main.p
USING CustomerService.
USING CustomerRepositoryImpl.
DEFINE VARIABLE repository AS CustomerRepositoryImpl NO-UNDO. DEFINE VARIABLE service AS CustomerService NO-UNDO.
repository = NEW CustomerRepositoryImpl().
service = NEW CustomerService(repository).
service:registerCustomer("1", "John Doe", "john.doe@example.com").
MESSAGE service:findCustomerById("1"):getName().
Cette structure permet de maintenir une séparation claire entre la logique métier et les détails de l'implémentation, rendant ainsi le code plus modulaire et plus facile à tester.
Ce diagramme montre les relations entre les différentes classes de notre architecture.
Ce diagramme montre les principales interactions entre l'utilisateur et le système.
Ce diagramme montre l'ordre des appels entre les objets pour un scénario donné, comme l'enregistrement d'un client.
Que l’on soit dans le monde Progress OpenEdge ou non, l'architecture hexagonale permet de construire des applications robustes et évolutives en séparant clairement la logique métier des détails techniques. Cela rend le code plus facile à maintenir et à tester, tout en permettant une flexibilité accrue pour les changements technologiques.
Ceci est particulièrement utile pour les éditeurs de logiciels métier dont les règles métiers sont maintenues durant plusieurs dizaines d’années.
Quadza Software peut accompagner vos équipes dans la durée pour leur permettre de mettre en place une telle approche.
Patrick