SDK pour vous, SDK pour moi, SDK pour tout le monde! Comment créer un SDK et pourquoi est-il nécessaire


Bonjour à tous!


Notre entreprise propose un service de stockage et de traitement de données d'appareils industriels (pompes, perceuses et autres équipements industriels). Nous stockons les données de nos clients et fournissons des fonctionnalités pour leur analyse: rapports de construction, graphiques et bien plus encore.


Et au cours du travail, nous avons remarqué que l'intégration de chaque nouveau client est fortement retardée, et le nombre d'erreurs diverses ne cesse d'augmenter. Ensuite, il est devenu clair qu'il était temps de régler ce problème. Comme une analyse de la situation l'a montré, le service informatique de chacun de nos clients a développé sa propre solution pour collecter localement les données des appareils et les envoyer à notre service. Cela complique le fait que, compte tenu des spécificités de l'industrie, il n'y a pas toujours accès à Internet et qu'il est nécessaire de stocker les données localement et de les envoyer le plus rapidement possible. Et il existe un nombre suffisamment important de telles nuances, ce qui entraîne une augmentation du nombre d'erreurs.


Et puis nous avons réalisé que la meilleure solution dans cette situation serait de développer un SDK et de le fournir au client. Immédiatement, j'ai commencé à rechercher les meilleures pratiques et considérations sur le développement du SDK et j'ai été très surpris - il n'y a pratiquement rien à ce sujet dans RuNet, mais il y a très peu d'informations sur Internet Basurmani et elles sont dispersées. Eh bien, la tâche est claire, réfléchie et mise en œuvre.


Mais c'est le manque d'informations sur ce sujet qui a créé le désir de faire part à la communauté des réflexions, des décisions prises et des conclusions sur le développement du SDK. Cet article traite d'une solution pour .NET, mais c'est un concept, il sera donc intéressant pour beaucoup. Détails sous la coupe!


Il est temps d'être déterminé


Commençons par définir ce qu'est le SDK et pourquoi il pourrait être nécessaire.


Le SDK (du kit de développement logiciel anglais) est un ensemble d'outils de développement qui permet aux spécialistes logiciels de créer des applications pour un progiciel spécifique, un logiciel de développement de base, une plate-forme matérielle, un système informatique, des consoles de jeu, des systèmes d'exploitation et d'autres plates-formes. Le SDK tire parti de chaque plate-forme et réduit le temps d'intégration.
...
Un ingénieur logiciel reçoit généralement un SDK du développeur du système cible.

Eh bien, c'est logique. En termes simples, le SDK est un ensemble de bibliothèques, afin que le client puisse facilement et rapidement commencer à travailler avec votre système (dans cet article, nous parlerons de notre service, mais tout ce qui est décrit dans l'article s'applique à d'autres types de SDK) ou effectuer les mêmes actions.


Mais, comme toute approche, le SDK Path présente à la fois des avantages et des inconvénients.


Les avantages


Intégration à grande vitesse d'un nouveau client - vos clients ont besoin d'écrire moins de code.


Réutilisation du code - le même code est utilisé à plusieurs endroits à la fois. Nous pouvons dire qu'il s'agit d'une duplication du paragraphe précédent, mais nous parlons du fait que la logique du travail est partout solitaire, ce qui implique


Prévisibilité du comportement - l'utilisation des mêmes bibliothèques amène le comportement des systèmes à un certain niveau, ce qui facilite grandement la recherche et l'élimination des erreurs et des vulnérabilités.


La qualité du code est l'endroit où de nombreuses personnes aiment économiser sur les tests (désolé pour le budget, les délais et autres raisons). Il est clair que dans le monde réel, tester toutes les sections du projet avec des tests est une tâche très laborieuse. Mais tester qualitativement tous les modules du SDK, puis les utiliser est un moyen d'augmenter le pourcentage de couverture des tests, ce qui entraînera une réduction du nombre d'erreurs.


La documentation est le même scénario qu'avec les tests. Documenter l'ensemble du projet est assez problématique. La réutilisation des SDK augmente le pourcentage de couverture de la documentation, ce qui abaisse le seuil d'entrée de nouveaux employés dans le projet et contribue généralement à la vie.


Tous les avantages, en fait, sont les conséquences de la chose la plus importante - nous écrivons le code de très haute qualité une fois, puis nous le réutilisons .


Inconvénients


Les exigences de qualité élevées du code SDK sont le résultat de l'avantage principal. Une erreur dans le SDK générera des erreurs dans tous les systèmes l'utilisant.


Définition de contraintes - Le SDK est un ensemble de bibliothèques pour implémenter des scripts standard . Parfois, les développeurs du SDK pensent qu'en plus d'implémenter l'un des scénarios fournis, le client n'a besoin de rien, qu'il est plus facile pour le client de tout faire à partir de zéro que de construire un piédestal à partir de béquilles pour le SDK.


Enfer de dépendance et mises à jour - lors de l'extension de la fonctionnalité (par exemple, personnalisation d'une solution pour un client spécifique), vous publierez une nouvelle version de la bibliothèque. Mais il existe des dépendances, différents ensembles de versions de bibliothèque pour différents clients, et vous devez surveiller attentivement la compatibilité descendante ou le contrôle de version strict.


Quand le SDK est vraiment nécessaire


Vous disposez de plusieurs scénarios standard qui sont mis en œuvre de temps en temps - en fait, notre cas.


Développement interne - dans différents projets, utilisez-vous des systèmes de journalisation, des configurations système, en travaillant avec HttpRequest, des bases de données, des fichiers? Créez un SDK interne - un ensemble de bibliothèques à usage interne. Vous pouvez étendre la fonctionnalité du SDK à tout moment, mais la vitesse de développement de nouveaux projets, le pourcentage de couverture avec des tests et de la documentation augmentera et le seuil d'entrée des nouveaux développeurs diminuera.


Lorsque le SDK est susceptible d'être redondant


Les scénarios d'utilisation ne sont pas définis ou changent constamment - laissez la mise en œuvre de solutions personnalisées aux clients et aidez-les. Pas besoin de faire un prodige de wunderwaffle, qui ne fera qu'interférer. Très pertinent pour les jeunes entreprises et startups.


Vous ne savez pas comment le faire qualitativement - j'ai de mauvaises nouvelles pour vous: il est temps d'apprendre. Mais donner une décision de travers à un client est très, très mal. Les clients doivent être respectés, après tout.


Nous avons donc décidé ce qu'est le SDK, avec ses avantages et ses inconvénients, et quand nous en avons besoin. Si après cela, vous avez réalisé que le SDK est vraiment nécessaire - je vous invite à vous lancer dans le "chemin du SDK" et à comprendre ce qu'il devrait être et comment diable le faire?


"Aimez-vous Lego?" - Modularité


Imaginez tous les scénarios possibles pour utiliser le SDK (vous avez déjà décidé pourquoi vous en avez besoin, non?) Et créez un script pour la bibliothèque. Qu'est-ce qui n'est pas une option? Mais c'est une mauvaise approche, et donc nous ne le ferons pas. Et nous serons comme ça:


  • décomposer tous les scripts en étapes
  • identifier les étapes communes
  • construire une liste de modules qui implémentent toutes les étapes possibles (un module est responsable de l'implémentation de quelque chose de spécifique, par exemple, travailler avec des configurations)

Par exemple, en tenant compte des spécificités de la tâche, nous avons besoin que toute la logique soit définie à partir des configurations. Nous implémentons le module pour travailler avec les configurations (lire, écrire, mettre à jour, valider et traiter les configurations) et nous l'utiliserons dans tous les autres modules.


Et pour la mise en œuvre de scénarios standard, nous allons vraiment créer des modules - une sorte de modules de «contrôle», chacun implémentant un scénario spécifique en utilisant d'autres modules du même SDK. Ainsi, pour l'implémentation de scénarios standard, le client n'a besoin que de connecter le module de contrôle du script (et il récupérera toutes les dépendances), et pour l'implémentation de dépendances non standard, nous utilisons les modules de base, réutilisant également le code.


C'est précisément la raison pour laquelle le SDK ne devrait pas être une seule bibliothèque (bien que je le veuille vraiment, je comprends. Après tout, lorsque l'ensemble du SDK est dans une seule bibliothèque, vous pouvez oublier les dépendances et tout ce qui y est lié), mais être un ensemble de bibliothèques. Un avantage supplémentaire de cette approche sera la réduction du «poids» du programme client - il tirera un SDK lourd et ne tirera que les modules nécessaires.


Mais vous ne devriez pas produire de modules de toute façon, car plus il y a de modules, plus il y a de maux de tête à partir de leurs dépendances! C'est-à-dire Il est important de diviser correctement la logique en modules, en maintenant un équilibre entre la décision «tout en un» et «chaque module a son propre module».


"Et c'était donc possible?!" - polyvalence


Fournissez au client diverses interfaces pour travailler avec votre bibliothèque. Je vais donner un exemple:


public void LoadConfiguration(string filename); public async Task LoadConfigurationAsync(string filename); 

Si vous fournissez uniquement la version synchrone, lors de l'implémentation d'une application asynchrone, le client sera obligé de faire des wrappers asynchrones de votre méthode synchrone. Si vous fournissez uniquement la version asynchrone, la situation est similaire. Donnez au client les deux et il vous remerciera.


Les génériques seront un plus. Par exemple, nous avons une classe pour travailler avec des configurations qui implémente des méthodes pour compresser une configuration dans une chaîne, charger une configuration à partir d'un fichier, etc. La configuration d'un module spécifique sera héritée de notre classe de base, mais pour travailler avec la nouvelle classe, nous devons également fournir des méthodes de décompression.


 class BaseConfiguration{ public BaseConfiguration FromString(string source){...} public BaseConfiguration FromString(string source,Type configurationType){...} public T FromString<T>(string source) where T:BaseConfiguration } class CustomConfiguration : BaseConfiguration{} 

Ainsi, nous avons fourni au client trois implémentations qu'il peut utiliser. Les génériques sont très pratiques, mais lorsque vous travaillez avec des types dynamiques, ils ne peuvent être appelés que par réflexion, ce qui n'est pas rentable. J'espère que le principe général d'universalité est clair.


"Parent 1, Parent 2, Enfants []" - Attribution d'un nom


Quelle est la partie la plus difficile d'un programmeur? Inventez les noms des variables.

Néanmoins ... La dénomination correcte des modules, classes, propriétés et méthodes aidera grandement ceux qui travailleront avec votre SDK. Exemple ne nécessitant aucun commentaire:


Exemple de SDK Kinect 2.0


 var skeletons = new Skeleton[0]; using (var skeletonFrame = e.OpenSkeletonFrame()) { if (skeletonFrame != null) { skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo(skeletons); } } if (skeletons.Length == 0) { return; } var skel = skeletons.FirstOrDefault(x => x.TrackingState == SkeletonTrackingState.Tracked); if (skel == null) { return; } var rightHand = skel.Joints[JointType.WristRight]; XValueRight.Text = rightHand.Position.X.ToString(CultureInfo.InvariantCulture); YValueRight.Text = rightHand.Position.Y.ToString(CultureInfo.InvariantCulture); ZValueRight.Text = rightHand.Position.Z.ToString(CultureInfo.InvariantCulture); 

Tout est clair d'après les noms des classes et des méthodes. Et s'il y a du code dans votre IDE, il est souvent possible de ne pas regarder dans la documentation si tout est déjà clair.


"Je suis sûr que si la mort savait ce qu'était la bureaucratie, les gens ne mourraient jamais, faisant toujours la queue ..." - Documentation


Mais même si tous les modules, classes, méthodes et propriétés sont très joliment et urgemment nommés, vous devez toujours écrire de la documentation. Premièrement, cela vous épargnera grandement les nerfs (le nombre de questions des clients est réduit d'un ordre de grandeur. Tout est dans la documentation), et deuxièmement, il est toujours clair pourquoi vous avez fait cela et pas autrement.


La documentation du SDK est généralement simple et concise. Il est généralement divisé en deux parties: Tutoriel - un cours étape par étape dans le style de "Construire une ville en 10 minutes" et la section Référence - une référence à tout ce qui peut être fait à l'aide de ce SDK.

Nous avons choisi le moyen le plus simple - résumé + articles. Nous ajoutons des attributs Xml pour les méthodes et les classes qui brillent dans intellisense sous forme d'infobulles. En utilisant Docfx, nous construisons une documentation sur ces attributs et obtenons une documentation détaillée et pratique, qui est complétée par des articles décrivant des cas d'utilisation et des exemples.


"- Pour le garder propre! - Comment vais-je le nettoyer avec une fourchette?" - Test


Que dire du test dans le cadre de la discussion sur le SDK ... La meilleure solution serait TDD (malgré le fait que j'ai une attitude négative envers cette approche, dans ce cas j'ai décidé de l'utiliser). Oui, longtemps. Oui, ennuyeux. Mais à l'avenir, vous ne vous accrocherez pas aux chutes constantes du SDK sur le côté et aux conséquences de cette chute.


Le principal jus de la situation est qu'en donnant le SDK au client, vous perdez le contrôle: vous ne pouvez pas corriger rapidement l'erreur, il est difficile de trouver cette erreur et vous aurez l'air assez stupide dans une telle situation. Par conséquent - test. Testez mieux. Et encore une fois. Et juste au cas où, testez vos tests. Et teste les tests. Donc, quelque chose m'a emporté, mais l'importance de tester le SDK, j'espère, est claire.


"Une victime qui n'a pas pu résister à son passé a été consommée par lui" - Logi


Étant donné que vous donnez le SDK à une société tierce, à la suite de laquelle vous perdez le contrôle de la situation, en cas d'erreur (au stade des tests, vous avez tous décidé «ça va faire», non?), Un processus assez long et douloureux vous attend pour rechercher cette erreur. C'est là que les journaux viennent à votre aide.


Enregistrez tout , absolument tout, et si une erreur se produit, demandez à votre client des journaux. De cette façon, vous économiserez beaucoup de temps et ne pourrez pas vous frotter le visage devant le client.


"Alarme! Achtung! Attention!" - Erreurs



Tout en réfléchissant beaucoup aux erreurs, je suis arrivé à une conclusion intéressante - pas une seule méthode dans votre SDK ne devrait donner une erreur qui n'est pas décrite dans la documentation . Vous devez admettre que c'est très désagréable lorsque vous connectez une bibliothèque tierce pour travailler avec HttpRequest, et cela vous lance des NullPointerException et StackTrace, ce qui vous emmène dans les entrailles de la bibliothèque. Et vous devez plonger dans ces «entrailles», en essayant de comprendre la profondeur du terrier du lapin et quel est en fait le problème.


Par conséquent, je propose la solution suivante - déclarer une liste fermée d'exceptions possibles et les documenter. Mais, parce que vous ne pouvez pas être sûr que vous avez tout fourni, envelopper la méthode dans un try-catch et l'erreur interceptée dans celle déclarée. Par exemple, une ConfigurationException qui contiendra une InnerException est une erreur interceptée. Cela permettra à un développeur tiers de détecter toutes les erreurs possibles, mais si quelque chose se produit, déterminez rapidement quel est le problème.


Versions ou "comment ne pas se mordre la queue"


Pour éviter de futurs problèmes, je recommande fortement d'utiliser un contrôle de version strict. Choisissez le système de version qui vous convient et utilisez-le. Mais si la nouvelle version de la bibliothèque n'a pas de compatibilité descendante, cela doit être indiqué. Comment le résoudre - vous pensez. Mais vous devez certainement y penser.


"Un train qui pourrait" - Déployer


Le besoin de pertinence de la documentation et des versions entraîne l'exigence d'exactitude du déploiement. Dans notre décision, nous utilisons la solution suivante (béquilles, mais elles fonctionnent).
Lorsqu'il est nécessaire de publier une nouvelle version, le développeur tire le bat'nik avec le numéro de version, puis le fichier de commandes:


  • version de build
  • place toutes les bibliothèques dans les archives
  • construire la dernière version de la documentation (docfx)
  • indique la version finale dans la documentation et au nom de l'archive
  • met tout ce qu'il y a de plus frais dans le dépôt git
  • WebApp sur MS Azure récupère une nouvelle validation de hook git et publie les modifications

À la sortie, nous obtenons une version mise à jour du site avec de la documentation, d'où vous pouvez télécharger l'archive avec la dernière version du SDK.
Les plans futurs incluent le tout dans les packages Nuget et sa publication dans le référentiel Nuget local.


Je recommande de prêter attention à ce point, car vous pouvez réduire considérablement le nombre de maux de tête causés par le manque d'informations pertinentes sur la nouvelle version de la bibliothèque.


"-Et alors tu peux? - Conneries. Regarde comme ça devrait!" - Exemples et boîte à outils


Un point important dans la documentation est les exemples d'utilisation. Mais en plus de cela, il est souvent nécessaire de fournir non pas une bibliothèque, mais une application qui implémente les scénarios les plus standard. Je recommande de créer ces applications avec du code source ouvert et bien commenté, qui vous permettra de tuer deux oiseaux avec une pierre - fournissez une application qui fonctionne et donnez un exemple d'utilisation du SDK.


Conclusion


Le développement du SDK est devenu une nouvelle tâche intéressante pour moi, ce qui a soulevé de nombreux problèmes architecturaux importants. Beaucoup de choses décrites dans l'article sont des choses évidentes (pour moi), mais je considère qu'il est important d'annoncer même les choses évidentes afin d'avoir une vue d'ensemble claire.


PS


Merci d'avoir lu, je serai heureux de vos commentaires. J'espère que cet article vous sera utile.

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


All Articles