1. Implémentation d'objets métier. Les classes qui encapsulent les règles métier sont la base d'une véritable programmation orientée objet. Dans cet article, nous couvrirons tous les aspects de la programmation et remettrons en question certaines de nos méthodes habituelles d'écriture de programmes Delphi. Le concept de base derrière ces méthodes de conception est l'encapsulation : concevoir un ensemble de classes avec des interfaces (méthodes) clairement définies qui disposent de méthodes pour opérer sur leurs propriétés. Ce concept sera utilisé tout au long du programme et aura un fort impact sur la manière dont les données sont enregistrées et présentées. Je voudrais présenter aux lecteurs l'article de Francis Glassborow sur le C++. Bien que les langages soient différents, les excellents concepts de conception de classe sont indépendants du langage. La plupart des programmes écrits en Delphi aujourd'hui ne sont pas orientés objet. Ce n’est pas parce qu’il existe un modèle objet dans le langage et qu’il utilise des classes originales ou nouvelles que le programme est véritablement orienté objet. La réutilisation du code prend fin lorsque les contrôles tiers sont glissés sur les fenêtres, mais les interdépendances entre les fenêtres et les unités prolifèrent rapidement. (!!!) Si vous souhaitez modifier la base du programme à l'avenir (comme passer à une base de données différente ou passer d'une structure à deux niveaux à une structure à trois niveaux), cela sera sérieusement gêné ou coûteux. Si le programme est véritablement écrit de manière orientée objet, il sera très pratique plutôt que restrictif. Bien entendu, l’écriture d’un tel programme nécessite une amélioration des concepts, et il y a un manque de productivité au début. La plupart des équipes de développement ne sont pas disposées à le faire ou à l’envisager. J'espère qu'à travers cet article je vous montrerai comment écrire de meilleurs programmes. Le résultat est un système plus fiable, facile à entretenir, de style cohérent, flexible, réutilisable et qui fonctionne mieux que les programmes écrits de manière traditionnelle. Surtout pour les gros programmes, les programmes dont le code est clair et véritablement orienté objet nécessiteront moins de ressources de maintenance que le même programme écrit de manière traditionnelle. La plus grande fiabilité des programmes orientés objet vient du fait que les données et les opérations sont encapsulées dans des classes bien définies. Le compilateur applique les classes, méthodes et propriétés correctes dans le code grâce à une puissante vérification de type, et il ne devrait y avoir aucune possibilité de mal comprendre l'intention du code si une modification future affecte l'ensemble du programme. Lorsque les classes sont utilisées correctement, les relations entre elles vont de soi et la majeure partie du code se concentre réellement sur l'essentiel du programme, plutôt que de réfléchir à des détails tels que la façon dont les données sont conservées. La simplicité et la cohérence tout au long du code amélioreront considérablement la maintenabilité du programme. Comme nous le verrons, l’utilisation intensive de l’héritage de classes augmente la productivité et la fiabilité, et améliore la cohérence. Ces cohérences se reflètent dans le code affiché, notamment dans le comportement des classes, la manière dont les données sont stockées et la manière dont l'interface utilisateur présente les données. Étant donné que la plupart des fonctionnalités sont fournies dans les classes de base, vous pouvez modifier fondamentalement votre programme en modifiant rapidement son comportement. (Par exemple, l'interface d'interaction utilisateur passe d'un formulaire piloté par fenêtre à un formulaire basé sur HTML.) Ces classes de base peuvent être conçues pour être indépendantes du programme, de sorte qu'un deuxième programme similaire obtienne immédiatement un gain de productivité. Un bon ensemble de cours de base peut apporter une amélioration significative allant jusqu'à 50 % pour un programme modeste en termes de temps, de coût et de fiabilité. La première chose à souligner est que le passage à un véritable développement orienté objet n'est pas une affaire anodine. Pour la première fois, vous devez vous assurer que vous avez bénéficié d'une assistance, ou que le programme est petit et qu'il n'y a pas de délai de livraison urgent ; Il convient de noter qu'une solution orientée objet (OO) n'est pas de dicter quelles classes doivent être utilisées et quelles classes ne doivent pas être utilisées dans le programme. Si une entreprise développe ses propres contrôles visuels ou utilise des contrôles visuels tiers, les classes de base La première étape de la conception de tout programme orienté objet consiste à déterminer quelles classes sont nécessaires. Il s’agit d’une étape absolument fondamentale, sous réserve des garanties techniques de divers autres développements, car les erreurs commises au début seront coûteuses à corriger. Lors de la conception de nos classes, nous nous efforçons généralement d'obtenir un faible couplage et une cohésion élevée : les classes sont aussi indépendantes que possible, mais peuvent être combinées de manière puissante. Une façon d’atteindre cet objectif consiste à diviser les classes en différentes catégories selon les différents rôles qu’elles jouent dans leurs programmes. Une sélection correcte de ces rôles se traduira par un ensemble cohérent de classes. Il existe un principe de base cohérent dans la conception du rôle des classes : diviser les responsabilités de la classe en présentation, application et stockage persistant des données (généralement dans une base de données). Bien que cela soit identique au partitionnement de programmes de bases de données à trois niveaux, il est important de noter que ce concept de partitionnement peut être implémenté dans une variété d'environnements : des programmes monopuce aux programmes distribués à plusieurs niveaux. Le groupe de classes qui composent la logique de l'application est responsable des travaux les plus difficiles, comme la réponse aux demandes d'actions des utilisateurs et le traitement des données. Certaines classes de cette couche représentent des entités du monde réel et sont modélisées par le système. Ces classes sont souvent appelées « classes commerciales » ou « classes de domaines problématiques ». Ils constituent une partie essentielle de tout programme orienté objet et, comme d'autres classes les prennent en charge d'une manière ou d'une autre, ils deviennent le centre d'intérêt de tous les développeurs. Identifier les objets métier présents dans un programme particulier est généralement une question d'expérience et d'instinct, bien qu'il existe toute une discipline (ou un art ?) dans ce processus. Les avantages de l'orientation objet par rapport aux techniques traditionnelles telles que SSADM(1) sont présents. tout au long de l'analyse, de la conception et du processus de maintenance des entités : chaque objet métier peut être représenté via l'analyse orientée objet (OOA), la conception orientée objet (OOD) et la programmation orientée objet (POO). Nous explorerons plus tard certaines techniques permettant d’identifier des cibles commerciales appropriées. Nous supposons d’abord que les processus suivants ont été terminés. L'intercommunication des classes entre les différentes couches (présentation, application et persistance) est clairement définie et interconnectée. La relation entre ces classes est illustrée dans la figure 1. Les flèches dans la figure montrent que les classes de la même couche peuvent appeler des méthodes dans une autre classe. Cette image montre également que les classes de la couche présentation (interface utilisateur) peuvent exploiter la couche application ou d'autres classes de l'interface utilisateur. La couche application (objets métier) peut exploiter les classes de la couche application et appeler les méthodes de persistance. La couche de persistance ne répond qu’à la demande de la couche application. Objets métier Pour démontrer comment les objets métier sont implémentés, nous verrons ensuite un programme simplifié avec des entités d'inventaire, de client et de commande (une entreprise fournit une certaine quantité de biens et les clients achètent ces biens). Notre analyse initiale a déterminé que trois objets métier étaient nécessaires pour représenter ces entités. Il y aura trois classes dans notre programme Delphi : TStockItem, TCustomer et Torder. Les interfaces publiques de ces classes sont présentées dans le listing 1. Il convient de souligner ici que les caractéristiques de ces classes sont exposées à l'extérieur via des propriétés (PRerty) : il s'agit d'une conception de classe simple et avantageuse qui contrôle l'accès externe via des propriétés. De plus, ces propriétés doivent se trouver dans la zone publiée de la classe (pour des raisons qui seront mentionnées plus tard) et se voir attribuer des valeurs par défaut appropriées. Bien que ces qualifications de propriété ne soient utilisées que lors du streaming de classes, elles donnent à chaque propriété une valeur initiale appropriée et rendent le code plus auto-descriptif. Cadre de première classe Dans les premières étapes de développement du programme, nous avons identifié et mis en œuvre trois objets métier. Ces trois objets jouent un rôle commun : représenter d’une manière ou d’une autre des entités du monde réel. Par conséquent, nous voulons qu'ils aient des propriétés similaires et des niveaux appropriés à ceux des entités du monde réel. Nous donnerons à chaque objet une classe de base commune appelée TPDObject (Problem Domain object). Au fil du temps, nous ajouterons des méthodes et des propriétés publiques à cette classe, et TPDObject continuera à être étendu. Il est à noter que TPDObject ne doit (jamais) comporter d’éléments liés à une application spécifique. En tant que classe indépendante du programme, elle est placée dans une unité indépendante et constitue la base du framework : un ensemble de classes qui peuvent être réutilisées dans de nombreux programmes. À l'avenir, notre cadre sera considérablement étendu pour former des classes de base qui fournissent des fonctions importantes indépendantes du programme et peuvent être rapidement utilisées dans des systèmes spécifiques. Nos TStockItem, TCustomer et Torder sont des objets personnalisés pour des systèmes spécifiques de TPDObject. TMyAppPDObject est une classe héritée de TPDObject.Bien que sa partie implémentation soit vide, c'est une bonne démonstration si nous ajoutons certains éléments à un programme spécifique et affectons toutes les classes de domaine problématiques dans le programme, comme ceci. La hiérarchie des classes devrait être plus appropriée. Le code initial du framework est répertorié dans la liste. La classe TPDObject fournit également uniquement un ID d'attribut en lecture seule, son type est TobjectID. Cet attribut donne à chaque objet un identifiant : nous considérerons deux instances de même type et ID comme étant le même objet. Ici, l'ID est intentionnellement déclaré comme son propre type pour éviter d'être directement affecté à une valeur d'un autre type standard. Le type de TobjectID n'a pas été spécifiquement choisi : ici j'ai choisi entier, qui peut aussi être une classe spécialisée dans certains cas. Bien que l'utilisation de classes comme identifiants semble être une approche plus purement orientée objet, basée sur le fait que les classes de notre domaine problématique seront créées et publiées des milliers de fois pendant l'exécution du programme, afin d'éviter la charge supplémentaire lors de la création. et en libérant des objets, je ne l'ai pas fait (en tant que puriste, j'inclus TobjectID dans TPDObject en tant qu'objet composite). Dans le code, il existe une paire de fonctions qui convertissent les chaînes en nos types d'identification d'objet et une constante qui sert de valeur initiale lorsqu'aucune affectation n'est effectuée. Il existe de nombreuses classes dans lesquelles l'identification des objets est mentionnée : certaines disent que tous les objets métier doivent recevoir une identification (même un GUID) qui n'est pas répétée dans le programme lors de leur création. En fait, être capable de distinguer différents objets dans un contexte donné est ce qui est vraiment important, et garder cela simple présentera des avantages évidents en termes de performances et d'espace de stockage. Questions sur les spécifications : afin de renforcer certains concepts et pratiques de conception lors de la conception de cadres de classe, je poserai quelques questions et demanderai aux lecteurs de réfléchir aux principes de base qui les sous-tendent. J'ai mentionné que la véritable conception orientée objet n'interdit pas l'utilisation de classes spécifiques, mais il existe une exception importante. Quelle est cette exception (la réponse se trouve dans la figure 1) ((( Listing 1 - Une unité de domaine de problèmes spécifique à l'application (abrégée) )))unit ProblemDomain;interfaceuses Framework;type TMyAppPDObject = class (TPDObject) end; TMyAppPDObject ) propriété publiée Nom : chaîne ; propriété QuantityInStock : propriété cardinale par défaut TradePrice : propriété de devise RetailPrice ; fin de la devise ; TCustomer = class (TMyAppPDObject) … ; TOrder = class (TMyAppPDObject) … ;implementationend.((( Fin du listing 1 )))((( Listing 2 - Une unité Framework indépendante de l'application )))unit Framework;interfaceconst NotAssigned = 0; tapez TObjectID = tapez Integer ; TPDObject = classe privée FID : TObjectID ; ID de propriété publique : TObjectID lit le FID par défaut NotAssigned ; end;function StrToID (Value: String): TObjectID;function IDToStr (Value: TObjectID): String;implementation…end.((( End Listing 2 )))(1) SSADM (Structured Systems Analysis & Systems Design) a été créé en 1981 Site Web de la Central Computer and Telecommunications Agency (CCTA) du gouvernement britannique : http://www.ccta.gov.uk ; ) a développé des méthodes standard d'analyse et de conception de logiciels. Philip Brown est consultant en conception de systèmes et développeur, présentateur et formateur actif. Il fera la promotion des avantages des techniques d'OO solides pour fournir de meilleures applications dès que l'occasion se présente. Vous pouvez le contacter à [email protected].