L'histoire d'une application réussie de SPR dans un projet Legacy

Dans cet article, je vais vous raconter, en prenant l'exemple de l'évolution de mon projet, l'histoire de la transition et la vision de la programmation contractuelle.

Au début, je voulais nommer l'article - «Programmation des contrats», dans la mesure où l'approche utilisée est de diviser toute la logique métier en contrats de données et en services clients utilisant ces contrats et interagissant les uns avec les autres à travers ces structures de données, de sorte que les mêmes La structure est traitée avec succès dans différents services.

Quelque chose que je vais décrire dans ma propre langue.

L'histoire de ma transition vers la programmation sous contrat a commencé avec le fait que j'avais un projet hérité envahi par une vaste gamme de fonctionnalités différentes dans le même domaine d'activité. De plus, tout cela était encore du multithreading et de la personnalisation pour différents clients. Plus précisément, le domaine d'activité était l'échange de documents électroniques juridiquement pertinents entre le système comptable, les services de fichiers et les services cloud.

Au cours du développement du système, de nouvelles exigences commerciales sont apparues et, en conséquence, le projet s'est rapidement développé et a été compliqué par de nouvelles fonctionnalités, ce qui a conduit à un moment donné à une architecture où le projet a commencé à ressembler à plusieurs applications distinctes avec des fonctionnalités connexes. Seule cette fonctionnalité a été implémentée, non pas à partir d'éléments communs, mais à partir de structures similaires mais implémentées différemment dans différents assemblys et espaces de noms.

Visuellement, une telle architecture peut être représentée comme plusieurs verticales de fonctionnalités

image

Une caractéristique d'une telle architecture était que si une exigence ou une erreur supplémentaire apparaissait, elle devait alors implémenter une telle tâche dans tous les «modules fonctionnels» du système, et non dans un domaine. Une autre caractéristique a été la présence dans le projet d'un grand nombre de constructeurs, ce qui a conduit à une telle division verticale du secteur d'activité. Le développeur implémente de nouveaux algorithmes pour les nouvelles exigences métier dans le code des constructeurs, ce qui conduit à l'émergence de nouvelles entités avec des structures différentes pour le même objet métier. Certes, cette approche peut être considérée comme plus orientée objet qu'une approche code-behind simple avec du code spaghetti. Ainsi, si vous voyez un grand nombre de constructeurs dans vos projets, la transition vers une approche contact simplifiera l'accompagnement et accélérera le développement de votre projet.

Une fois, dans l'entreprise, nous avons été confrontés au fait que le client avec lequel nous mettions en œuvre a commencé à exprimer que le système que j'ai développé produisait souvent des erreurs. Je ne pouvais pas contester cela, bien que des erreurs soient apparues périodiquement, mais elles ont été corrigées et certains clients ont fait installer et utiliser le système. Je dois dire merci que le client était nuisible et difficile, et a testé très soigneusement notre système pendant la période de mise en œuvre.

Moi aussi, je n'aimais pas le fait que je n'ai pas eu assez de temps pour le développement et le soutien, malgré beaucoup d'efforts, et à un moment donné, je n'avais tout simplement aucune idée de ce qui pourrait améliorer le système et le rendre plus stable.

La décision est venue soudainement et de façon inattendue.

J'ai bien compris que les mêmes objets métier sont implémentés différemment dans différents modules du système - documents de différents types, reçus, travailleurs, clients de service, clients de base de données, clients de fichiers avec la possibilité de stocker des documents dans différents formats (personnalisation pour différents clients;) )

Une partie de la logique a été implémentée dans des entités, ce qui a empêché l'utilisation des mêmes entités dans différents algorithmes.

J'ai alors décidé - il fallait créer quelque chose comme un seul constructeur avec des détails à partir desquels tous les algorithmes implémentés dans le système peuvent être assemblés. Ce qui est logique, car il réduit le nombre de classes similaires et simplifie la prise en charge.

J'ai décidé de diviser strictement "l'univers" de ma candidature en

  • contrats de données - structures de données qui contiennent et sont utilisées uniquement pour le stockage de données

    Documents
    Enveloppes
    Reçus
    EP
    ...
  • clients-services - J'écris spécifiquement que les clients sont des services, car lors de la mise en œuvre de chaque système qui interagit dans le domaine d'activité, je l'ai représenté comme une enveloppe sur ce système, dans lequel les méthodes de travail avec les contrats de date ont été mises en œuvre. Et en plus du fait que ces classes sont des wrappers sur les services, elles contenaient également la logique de liaison, les conversions et les transformations nécessaires pour simplifier la logique métier

De plus, les bûcherons s'accrochaient à ces clients. Cela vous a permis de trouver rapidement le point d'erreur par le journal. (à l'avenir, de nombreux appels ont disparu lorsque, par les journaux, les utilisateurs eux-mêmes ont commencé à comprendre où ils avaient commis une erreur - un système de fichiers, un réseau, un système de comptabilité ou le service Web de l'opérateur)

Par exemple
CloudClient - un client d'un service cloud auquel les documents sont envoyés et traités
- Télécharger
- envoyer
- Obtenez
- Télécharger
- D'accord
...

FileSystemClient - client de système de fichiers
ERPClient - système de comptabilité client

Les clients ont implémenté toutes les méthodes précédemment utilisées dans les algorithmes dans tous les modules, ce qui a permis d'implémenter rapidement et facilement les algorithmes nouvellement implémentés à partir des mêmes parties.

Et l'allocation de méthodes de fonctionnalité similaires dans les clients respectifs a conduit à une plus grande spécialisation et réutilisation du code.

L'architecture était maintenant un diagramme comme dans l'image

image

J'ai alloué tous les objets de base de mon concepteur à l'assemblage avec la fin du SDK (Software Developers Kit) et c'est devenu plus facile à travailler et surtout plus agréable. Le travail a déjà cessé d'être la création de béquilles et de solutions temporaires, et maintenant l'attitude envers le projet de l'intérieur est devenue plus sérieuse du fait que je voyais maintenant une énorme offre d'évolutivité et d'architecture compétitive. En effet, un tel fait a considérablement accru la motivation et ouvert de nouveaux horizons professionnels.

Sur la base du SDK créé, j'ai confié la mise en œuvre d'une couche de logique métier qui automatise la mise en œuvre de tâches directement métier. Étant donné que toutes les nuances techniques ont été apportées aux couches inférieures situées dans les clients, la mise en œuvre des mêmes algorithmes a été simplifiée et a commencé à paraître beaucoup plus agréable.

L'approche est simple, et permet de simplifier les développements futurs et ce qui est très important est d'augmenter la flexibilité de l'architecture. Oui, cela nécessitera une refactorisation approfondie. Dans mon cas, il a fallu 2 semaines de développement en mode fanatique. Mais après cela, je n'ai presque pas codé, car tout fonctionnait de manière stable.

Et grâce à la séparation des responsabilités (SPR) et des journaux, j'ai pu supprimer rapidement les erreurs des services tiers, entraînant des erreurs de mon côté. Auparavant, cela nécessitait des analyses qui prenaient beaucoup de temps.

Cette approche est bonne à utiliser sur certaines couches. Sur les couches supérieures de l'application, un modèle anémique peut être plus pratique, mais il est préférable de mettre en œuvre un modèle anémique basé sur une approche contractuelle.

Source: https://habr.com/ru/post/fr468853/


All Articles