Comment concevoir un logiciel extensible (architecture de plugin)? [fermé]
J'ai besoin de ressources qui parlent de la façon de concevoir votre logiciel pour être extensible, c'est-à-dire pour que d'autres personnes puissent écrire des add-ons/plug-ins qui ajoutent des fonctionnalités.
Que recommandez-vous? Toute ouvrages qui traitent de ce sujet?
Je préférerais quelque chose de court et précis; un peu de théorie et un tas d'exemples concrets.
Je ne cible pas un langage spécifique, je veux être capable de comprendre l'idée de base afin que je puisse l'implémenter dans n'importe quel langue.
Et pour la même raison, je préfère ne pas le faire en utilisant un framework que quelqu'un d'autre a construit (à moins que le framework ne soit pas très haut niveau, c'est-à-dire ne cache pas trop), pour le moment je veux seulement m'éduquer sur le sujet et expérimenter diverses façons de l'implémenter. De plus, un cadre suppose généralement les connaissances de l'utilisateur sur le sujet.
Mise à JOUR
Je ne demande pas à propos de la POO ou de permettre à mes classes d'être héritées. Je parle A propos de la conception d'une application qui sera déployée sur un système, de sorte qu'elle puisse être étendue par des add-ons tiers après son déploiement.
Par exemple, Notepad++ a une architecture de plug-in où vous pouvez placer un .fichier dll dans le dossier plugins, et il ajoute des fonctionnalités à l'application qui n'était pas là, comme le choix des couleurs, ou l'insertion d'extrait de code, ou bien d'autres choses (un large éventail de fonctionnalités).
13 réponses
Si nous parlons de. Net, essayez Scripter les applications. net avec VBScript sur CodeProject. Beaucoup d'exemples concrets là.
Voici les sites mettant en œuvre diverses techniques d'extension d'application
- ClearScript-rend V8, VBScript et JScript disponibles pour les applications. Net
- CS-Script - le moteur de Script C #
- Architecture de Plugin utilisant C #
- architecture du plugin Opinio
- Notes sur L'Architecture du Plug-in Eclipse
- Plug-In Architecture Framework pour les débutants
- architecture du plugin Gecko
- architecture du plugin Fungimol
OSGI est un bon exemple pratique d'un cadre technique permettant de faire ce que vous êtes après.
La théorie est ici .
L'extensibilité et la capacité d'écrire le plugin doivent traiter le cycle de vie du service
- Ajout / Suppression de service / plugin sur place
- gestion des dépendances entre les services
- gestion des états des services (déclarés, installés, démarrés, arrêté,...)
L'une des principales fonctions d'un module est comme une unité de déploiement ... quelque chose que nous pouvons soit construire ou télécharger et installer pour étendre les fonctionnalités de notre application.
Vous trouverez une bonne introduction ici , sur la notion centrale de service (ce qui est lié à votre question, et qui explique certains problèmes autour des services, élément clé pour extensibilité).
Extrait:
Pourquoi les services sont-ils si importants si tant d'applications peuvent être construites sans eux? Eh bien, les services sont le moyen le plus connu de découpler les composants logiciels les uns des autres.
L'un des aspects les plus importants des services est qu'ils minimisent considérablement les problèmes de chargement de classe car ils fonctionnent avec des instances d'objets, pas avec des noms de classe. Instances créées par le fournisseur et non par le consommateur. La réduction de la la complexité est assez surprenante
Non seulement les services minimisent la configuration, mais ils réduisent également considérablement le nombre de paquets partagés.
Vous essayez d'atteindre deux objectifs opposés:
- Les composants de votre logiciel doivent exposer Beaucoup {[5] } d'eux-mêmes, afin qu'ils puissent être réutilisés
- Les composants de votre logiciel doivent exposer Très peu {[5] } d'eux-mêmes, afin qu'ils puissent être réutilisés
Explication: pour encourager la réutilisation du code, vous devriez pouvoir étendre les classes existantes et appeler leurs méthodes. Ce n'est pas possible lorsque les méthodes sont déclarées "privées" et que les classes sont "finales" (et ne peuvent pas être proroger). Donc, pour atteindre cet objectif, tout devrait être public et accessible. Pas de données ou de méthodes privées.
Lorsque vous lancez la deuxième version de votre logiciel, vous constaterez que beaucoup des idées de la version 1 étaient carrément fausses. Vous devez changer de nombreuses interfaces ou votre code, les noms de méthodes, supprimer les méthodes, casser L'API. Si vous faites cela, beaucoup de gens se détourneront. Ainsi, afin de pouvoir faire évoluer votre logiciel, les composants ne doivent pas exposer tout ce qui n'est pas absolument nécessaire - au prix de la réutilisation du code.
Exemple: je voulais observer la position du curseur (caret) dans un texte de style SWT. Le curseur n'est pas destiné à être étendu. Si vous le faites, vous constaterez que le code contient des vérifications comme " est cette classe dans l'organisation du paquet.Eclipse.swt " et beaucoup de méthodes sont privées et finales et ainsi de suite. J'ai dû copier environ 28 classes de SWT dans mon projet juste pour implémenter cette fonctionnalité parce que tout est verrouillé.
SWT est un cadre agréable à utiliser et l'enfer pour étendre.
Bien sûr, il y a le fameux Principe Ouvert Fermé - http://en.wikipedia.org/wiki/Open/closed_principle
Implémentez les principesSOLID dans votre application.
1. Principe de responsabilité unique: Une classe ne devrait avoir qu'une seule responsabilité (c'est-à-dire qu'un seul changement potentiel dans la spécification du logiciel devrait pouvoir affecter la spécification de la classe
2.Principe ouvert / fermé: les entités logicielles ... doivent être ouvertes pour extension, mais fermées pour modification
3. Substitution Liskov Principe: Les objets d'un programme doivent être remplaçables avec des instances de leurs sous-types sans altérer l'exactitude de ce programme
4. Principe de ségrégation d'Interface: de nombreuses interfaces spécifiques au client sont meilleures qu'une interface à usage général
5. Principe d'inversion de dépendance: on devrait dépendre des Abstractions . Ne dépend pas des concrétions
Questions Stackoverflow:
Exemple de Principe De Responsabilité Unique
Le principe ouvert / fermé est-il une bonne idée?
Quel est le principe de Substitution de Liskov?
Principe de ségrégation D'Interface-programme sur une interface
Quel est le principe D'Inversion de dépendance et pourquoi est-ce important?
Eh Bien cela dépend de la langue.
- en C / C++, je suis sûr qu'il existe une fonction loadlibrary qui vous permet d'ouvrir une bibliothèque à l'exécution et d'invoquer ses fonctions exportées. C'est généralement ainsi que cela se fait en C/C++.
- dans. NET, il y a une réflexion, qui est similaire (mais plus large) à loadlibrary. Il existe également des bibliothèques entières construites sur la réflexion comme Managed extension Framework, ou Mono.Addins qui fait la plupart du levage de charges lourdes pour vous déjà.
- en Java, il y a aussi la réflexion. Et il y a le JPF (Java Plugin Framework) qui est utilisé dans des choses comme Eclipse IIRC.
Selon la langue que vous utilisez, je pourrais recommander quelques tutoriels / livres. J'espère que cela vous a été utile.
L'article écrire des applications basées sur des plugins explique clairement les responsabilités des différentes parties de l'architecture en utilisant un exemple très simple; le code source est fourni (VB.Net). Je l'ai trouvé très utile dans la compréhension des concepts de base.
Checkout "CAB" - Microsoft logiciel de Composition de blocs de Construction de Cadre. Je pense qu'ils ont une "version web" de trop...
Je viens de commencer à développer une application client intelligent. Ce sont deux options que j'envisage.
En utilisant le système de Microsoft.AddIn espace de noms. Semble très prometteur, mais il peut être un peu complexe pour notre solution finale.
Ou le Smart Client - Composite UI Application Block de Microsoft
Récemment, j'ai regardé prendre des composants à la fois le bloc D'Application de L'interface utilisateur Composite et le système.Ajouter un espace de noms pour créer le mien. Depuis la source le code est disponible pour la CABINE, il est facile à étendre. Je pense que notre solution finale sera une version légère de la cabine, en utilisant définitivement le bloc D'Application Unity
L'architecture du Plugin devient très populaire pour son extensibilité et donc sa flexibilité.
Pour c++, le serveur Apache httpd est en fait basé sur un plugin, mais un concept de module est utilisé à la place. La plupart des fonctionnalités apache sont implémentées en tant que modules, comme le cache, la réécriture, l'équilibrage de charge et même le modèle de threading. C'est un logiciel très modulaire que j'ai jamais vu.
Et pour java, Eclipse est définitivement basé sur un plugin. Le noyau D'Eclipse est un système de modules OSGI qui gère les bundles, un autre concept pour plugin. Bundle peut fournir des points d'extension sur lesquels nous pouvons construire des modules avec moins d'efforts. La chose la plus complexe dans OSGI est sa caractéristique dynamique, ce qui signifie que les bundles peuvent être installés ou désinstallés lors de l'exécution. Pas de cessez-le-monde syndrome de plus!
Si vous travaillez avec. Net, notre recherche a donné deux approches: le script et la composition.
Script
Vous étendez les fonctionnalités de ce que vos classes peuvent faire en les orchestrant à l'aide de scripts. Cela signifie exposer ce qui est compilé dans votre langue. Net préférée dans un langage dynamique.
Certaines options que nous avons trouvées méritent d'être explorées:
- IronPython
- IronRuby
- JavaScript: Jint , Jurassique et JavaScript .Net sont de bons points de départ.
- Script.Net -> celui-ci a été le premier à attirer notre attention.
Composition
Si vous démarrez un projet avec. Net 4 ou supérieur, vous devez jeter un bon coup d'œil au Managed Extensibility Framework (MEF). Il vous permet d'étendre les fonctionnalités de vos applications dans un plugin façon.
Le Managed Extensibility Framework (MEF) est une couche de composition pour . Net qui améliore la flexibilité, la maintenabilité et la testabilité de grandes applications. MEF peut être utilisé pour le plugin tiers extensibilité, ou il peut apporter les avantages d'un vaguement couplé architecture de type plugin pour les applications régulières.
Le cadre de complément géré est également une bonne lecture.
Puisque je n'ai pas assez de points de représentants pour laisser un commentaire, je poste ceci comme réponse. SharpDevelop est un IDE pour le développement D'applications en C# / VB. NET / Boo. il a une architecture assez impressionnante qui se permet d'être étendu dans un certain nombre de façons - à partir de nouveaux éléments de menu à la prise en charge du développement de nouveaux langages entiers.
Il utilise un peu de configuration XML pour agir comme une couche de colle entre un noyau de L'IDE et l'implémentation du plugin. Il gère la localisation, le chargement et versioning des plugins hors de la boîte. Le déploiement de nouveaux plugins consiste simplement à copier dans le nouveau fichier de configuration xml et les assemblys requis (DLL) et à redémarrer l'application. Vous pouvez lire plus à ce sujet dans le livre "Dissecting a Csharp application" par le(s) auteur (s) original (s) - Christian Holm, Mike Krüger, Bernhard Spuida de l'application de ici. Le livre ne semble pas être disponible sur ce site, mais j'ai trouvé une copie qui pourrait encore être autour de ici
Aussi trouvé une question connexe ici
Plutôt que de réinventer la roue, utilisez les cadres en main. Eclipse et Netbeans prennent tous deux en charge les extensions basées sur des plugins. Vous devez cependant travailler en Java.