Article
FONT SIZE :
fontsize_dec
fontsize_inc
Auteur: Admin
Vues: 3
Temps: 14:38:52 | 4 années depuis

Mise en œuvre des objets métier


Les classes qui encapsulent les règles de gestion de jeter les bases d'une véritable application orientée objet.

La mise en œuvre de Business Objects

Cet article est le premier d'une série où nous allons explorer les multiples facettes de la mise en œuvre d'une véritable application orientée objet. Sur le chemin nous allons prendre dans presque tous les aspects de la conception d'applications et de contester certaines des façons acceptées de rédaction d'une demande de Delphi. L'idée de base derrière cette approche est l'encapsulation: la conception d'un ensemble de classes avec des interfaces bien définies (méthodes) qui fonctionnent sur la propriété. Ces concepts seront imprégner toute l'application et influenceront grandement la manière dont les données sont stockées et présenté. Je conseillerais aux lecteurs d'étudier colonne C Francis Glassborow ++; même si le modèle d'objet n'a pas l'exhaustivité de Delphes (et la complexité) de C ++, les concepts de la bonne classe de conception sont indépendants de la langue.



La plupart des applications typiques aujourd'hui Delphi écrites ne sont pas orientés objet. Tout simplement parce que la langue a un modèle d'objet et de nombreuses nouvelles et des classes existantes sont utilisées, cela ne signifie pas que la demande peut être considérée comme véritablement OO. La réutilisation de code a pris fin avec la chute du tiers composants formes, et les interdépendances entre les formes et les unités de proliférer rapidement. Les possibilités futures pour la modification des applications critiques (telles que le tournage ou le déplacement des bases de 2-tier application 3-tiers) sont très limitées ou très coûteux à contempler. Rédiger la demande d'une manière réelle OO faciliter plutôt que de limiter ces possibilités. Cependant, la rédaction de ces applications nécessite un changement de mentalité, accompagné par un manque initial de la productivité, dont la plupart de l'équipe de développement ne sont pas disposés ou pas en mesure de prendre en considération. Dans le cadre de ces articles, je l'espère pour montrer certaines des bases qui aideront les développeurs à faire la transition vers la mise en œuvre de meilleures applications. Les systèmes qui en résultent seront plus fiables, gérables, cohérent, souple, réutilisable et en général de meilleurs résultats que d'une demande écrite d'une façon standard. En particulier, les avantages de la clarté du code sont telles que pour les grandes applications, on écrit dans un véritable OO peut nécessiter un nombre significativement plus faible de ressources de maintenance que la même demande écrite de traditionnel. Dois-je justifier ces supplémentaires OO performances de l'application: Je pense que quelques revient avec quelque chose à vendre (dans ce cas, la vision de meilleures applications) devrait fonctionner sans opposition!



La fiabilité accrue des applications OO provient du fait que les données et les opérations sont encapsulés dans des classes bien définies. Le compilateur encourager classe et à la méthode et à la propriété grâce à l'utilisation d'une vérification de type solide, et ayant unique plutôt que de dupliquer du code signifie que les changements futurs dans une seule routine sont répandus dans toute l'application. Une conséquence de l'utilisation correcte des classes est que les relations entre eux sont évidents et bien plus grande proportion du code écrit est en fait la mise en œuvre de la «viande» de l'application, plutôt que de se soucier de détails tels que la façon dont les données sont effectivement stockées persistante. Cela rend l'application beaucoup plus facile à maintenir, encore simplifié par un facteur supérieur cohérence à l'ensemble. Comme nous le verrons, en utilisant l'héritage de classe est beaucoup productivité augmente et la fiabilité, mais exige aussi une uniformité. Cette cohérence est évidente dans la façon dont le code est structuré et la manière dont ils se comportent classes, mais également la mesure de la façon dont les données sont stockées et la façon dont l'interface utilisateur est présentée. Comment la plupart des fonctionnalités est disponible dans la classe de base, vous pouvez rapidement modifier leur comportement d'influencer sensiblement l'application (par exemple, changer l'interface à base de HTML, plutôt que la formation dirigée). Ces classes de base peuvent être conçus pour être indépendants des applications, de sorte que la seconde requête écrite de cette manière génère une impulsion immédiate de la productivité. Un bon jeu de classes de base qui peut fournir jusqu'à 50% du code dans une application de taille moyenne, un avantage évident d'un temps, de coût et de fiabilité pieds. Et «raisonnable de souligner que la transition vers le développement OO" réel "n'est pas anodin et ne doit être effectuée pour la première fois avec l'aide d'experts, ou pour un petit projet, sans délais urgents. Il convient également de souligner que OO n'impose pas une solution d'autres classes qui doivent (ou ne doivent pas) être utilisés dans l'application. Si une entreprise a développé ses propres composants visuels, l'utilisation de ces tierces parties, ou a normalisé sur une plate-forme de base de données particulière, alors il n'y a aucune raison pour que ceux-ci ne peuvent pas être utilisés (avec une exception notable). OO développer une application est de l'application d'un ensemble cohérent de modèles de conception, plutôt que de dicter les composants à utiliser.



Leçons particulières

La première étape dans la conception de toute application orientée objet est de penser à des classes qui seront nécessaires. C'est une étape absolument essentielle, comme pour tout autre développement de la technique, comme toujours tort à un stade précoce sera coûteux à réparer. Dans la conception de nos classes devraient généralement s'efforcent de couplage faible et une forte cohésion - les classes devraient être aussi indépendant que possible des autres classes, mais vous devriez être en mesure de combiner de manière puissante. Une façon d'y parvenir est de catégoriser des groupes de classes par les rôles qu'ils auront dans l'application. Une sélection judicieuse de ces rôles se traduira par un ensemble cohérent de classes.



Il est une règle fondamentale qui revient tout au long du rôle de classe de conception: la forte séparation des classes responsables de la présentation, de l'application et de persévérance. La présentation peut être généralement satisfaits de la façon dont l'interface utilisateur, et la persistance comme quelque chose qui stocke des données (généralement dans une base de données). Même si c'est la même chose comme il en existe une séparation pour le développement de 3 niveaux, il convient de noter que cette séparation est une conception qui peut être réalisée de nombreuses manières: comme une seule application monolithique tout le chemin à travers un système multi-niveaux entièrement distribué. L'ensemble des classes qui composent la logique de l'application sont ceux qui font réellement le travail pour répondre à des stimuli aux utilisateurs de manipuler et traiter les données. Un sous-ensemble de classes à l'intérieur de cette couche est identifiée comme représentant des entités du monde réel, qui seront modélisées par le système. Ces classes sont souvent étiquetés comme "domaine" problème "entreprise" soit. Ils sont une partie essentielle de tout système de OO, comme la plupart des autres classes seront les soutenir d'une façon ou d'une autre, et former la pièce maîtresse de n'importe quel développeur de participation.



Identifier les objets métier pour une application spécifique devient généralement instinctive avec l'expérience, même si il ya toute une science (ou art?) Derrière le processus. La beauté de OO par rapport aux techniques traditionnelles telles que SSADM est que les processus d'analyse et de conception qui ont évolué conservent la même ampleur dans tous: vous pouvez voir une représentation de chaque objet métier dans tout l'OOA (analyse), OOD (conception) et enfin, la mise en oeuvre proprement dite (OOP). Nous allons explorer quelques-unes des techniques pour identifier les objets d'affaires dans le futur colonnes approprié. Pour l'instant, nous supposons que ces processus ont été effectuées.



La communication entre les classes qui existent dans les différentes couches (présentation, application, persistance) est bien défini et doit être respecté absolument. Ceci est illustré à la figure 1, et les flèches indiquent qu'une classe dans une couche peut faire des appels de méthode dans une autre classe. Ce diagramme montre que la couche de présentation (interface utilisateur) peut manipuler le niveau de la demande ou d'autres classes au sein de l'interface utilisateur, et que le niveau de l'application (objets métier) peut se manipuler et faire des appels dans la couche de persistance, qui ne peut répondre aux demandes de la couche d'application.



Les objets métier

Pour démontrer comment les objets métier peuvent être mises en œuvre, nous suivrons l'exemple de travailler avec un petit ensemble de classes qui exposent les entités photographies, Customer et Order classiques (une société propose une gamme d'articles en stock pour la vente, qui peuvent être achetés (à commander ) par le client). Notre (trivial) analyse confirme que nous avons d'abord richediamo trois objets métier pour représenter chacune de ces entités. Dans notre application Delphi nous aurons trois classes: TStockItem, tCustomer et torder. Listing 1 montre une interface publique réduite pour ces classes. Il est à noter que tous les attributs sont exposés comme des propriétés de la classe: Cette classe est tout simplement une bonne conception et facilite le contrôle de l'accès à la propriété (si nécessaire). Il est également à noter que les propriétés sont présentés dans la section publié de la classe (pour des raisons que nous verrons dans l'avenir), et qui sont pleinement qualifiés avec des valeurs par défaut si nécessaire. Bien que cette propriété qualificatif est apparemment utilisé lors de la diffusion des composants, il joue un rôle utile pour indiquer la valeur initiale de chaque propriété et aide le code auto-descriptif.



Quelque chose qui est essentiel pour l'entreprise (le domaine du problème) est que les objets peuvent avoir aucune connaissance de la façon dont ils sont stockés de façon permanente. Ils ne savent pas comment ils sont stockés dans des tables de base de données, en réalité, ils peuvent faire que des hypothèses sur le stockage que ce soit. Un objet métier est une classe très ciblée qui expose uniquement les propriétés et les méthodes appropriées nécessaires pour les manipuler. Lors de la conception de l'interface publique de la classe sans concessions doivent être faites à des types de propriété pour persistante (base de données) de stockage. Vous devriez toujours choisir le type le plus approprié pour la propriété en question, indépendamment de si oui ou non la base de données est destiné à ne pas les soutenir nativement. Un bon exemple est une propriété ensemble: certaines bases de données appuient directement l'ensemble, mais si c'est une façon naturelle pour exposer une propriété d'un objet métier alors il doit être choisi de préférence à une autre représentation (peut-être un certain nombre de booléen). Un autre exemple est d'exposer quelque chose comme une adresse comme TStringList. Ce n'est pas le rôle de l'objet de l'entreprise d'affecter son interface pour faciliter le dépôt de la base de données: c'est la tâche de la couche de persistance.



Notre première photo

Nous avons identifié et trois objets métier mis en œuvre comme base initiale pour notre application. Ces trois objets partagent un rôle commun: représenter des entités du monde réel, en quelque sorte. Nous nous attendons donc à avoir des propriétés similaires et une hiérarchie de classes est approprié. Nous allons donner à chacun de ces objets d'un ancêtre commun, appelé TPDObject (problème de domaine de l'objet). Cette classe sera étendue au fil du temps TPDObject introduire des méthodes et des propriétés communes dans nos cours. Il est à noter que TPDObject ne contient pas (et ne le sera jamais) éléments application spécifique. Comme une construction indépendante de l'application doit être placé dans une unité distincte et constitue la base d'un cadre: un ensemble de classes qui peuvent être réutilisés dans de nombreuses applications. Au fil du temps notre organisation étendra considérablement pour offrir de nombreuses classes de base qui fournissent une fonctionnalité significative indépendants des applications prêtes à être spécialisé pour les systèmes spécifiques. Nos leçons TStockItem, tCustomer et torder sont des exemples de versions spécialisées de notre TPDObject générique. A regarder de plus près la liste 1 montre que, en fait, nos trois classes de domaine de problème descendent tous d'une autre classe, TMyAppPDObject, lui-même un descendant de TPDObject. Bien que la mise en œuvre de TMyAppPDObject est vide, est un autre exemple de la bonne classe de conception d'une manière qui, si nous voulons fournir des éléments spécifiques à l'application dans l'ensemble de nos objets du domaine du problème est une classe appropriée dans notre hiérarchie.



Listing 2 montre notre cadre unités embryonnaire. Au moment où le TPDObject de classe ne fournit qu'une propriété en lecture seule nommée ID, qui est de type TObjectID. Cette propriété est utilisée pour donner le concept de l'identité de chaque classe: nous définissons deux cas en ce qu'ils représentent le même objet si elles sont du même type et ont la même valeur d'ID. Cela a été délibérément défini comme le propre type de sorte que l'affectation n'est pas directement compatible avec d'autres types scalaires. Le choix de TObjectID est arbitraire: dans ce cas, j'ai choisi de faire un type Integer, mais il ya une affaire à faire sa propre classe. Bien que plus "pur", j'ai décidé contre ce sur la base du fait que nos objets du domaine de problèmes seront construits (et détruit) plusieurs milliers de fois au cours de l'application et nous pouvons éviter le surcoût de la construction et de la destruction de la TObjectID de classe supplémentaire (mon argument puriste de ce choix est que la mise en œuvre TObjectID catégorie distincte a été intégrée dans le TPDObject de classe comme un objet composite). Il ya un couple de méthodes supplémentaires de cette unité à convertir notre type d'objet de l'identité à une représentation de chaîne, et une constante pour la valeur initiale «sans identité».



Il ya un certain nombre d'écoles de pensée sur l'identité d'un objet; il est dit que tous les objets métier doivent être affectés d'une identité lorsque que l'identité se construit et doit être unique au sein d'une application (ou même dans le monde entier comme un GUID). Dans la pratique, il est seulement important d'être capable de distinguer entre deux objets dans un contexte donné, et garder ce simple stockage et la performance présente des avantages évidents, mais certainement pas me trouver en faisant valoir contre un choix pour un type plus complexe des circonstances appropriées.



Une question d'éthique

Afin de mettre en évidence certains des problèmes de conception et de mise en œuvre des décisions prises lors de la conception d'un cadre qui parfois poser des questions, et inviter les lecteurs à regarder la logique derrière eux. Au début de la colonne je l'ai mentionné l'exception notable de la déclaration qu'une conception OO vraiment n'interdit pas l'utilisation de classes spéciales. Qu'est-ce que l'exception à cette déclaration (indice: la réponse se trouve dans la figure 1).



(((Listing 1 - Domaine spécifique problème Unité (abrégée))))



Unité ProblemDomain;



interface



utilisations

Cadre;



genre de

TMyAppPDObject = class (TPDObject)

fin;



TStockItem = class (TMyAppPDObject)

publié

Nom: String;

Propriétés QuantityInStock: Cardinal défaut 0;

Propriété TradePrice: valeur;

Immobilier Prix de détail: monnaie;

fin;



TCustomer = class (TMyAppPDObject) ...



Torder = class (TMyAppPDObject) ...



exécution



fin.

(((Fin de la cotation 1)))



(((Listing 2 - application Framework unité indépendante)))

Quadro unités;



interface



const

NotAssigned = 0;



genre de

TObjectID = Integer;



Classe TPDObject =

privé

FID: TObjectID;

public

ID de Propriété: TObjectID lu par défaut FID NotAssigned;

fin;



Fonction StrToID (value: String): TObjectID;

IDToStr fonction (valeur: TObjectID): String;



exécution



...



fin.

(((Fin Listing 2)))

(((Figure 1 - Classe interaction panoramique)))

(((Fine figure 1)))



Suivant dans la série

Commentaires (0)
Sans commentaires

Ajouter un commentaire

smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile
Caractères restants: 3000
captcha