关于语言不可知:如何设计可扩展软件(插件架构)?

How to design extensible software (plugin architecture)?

我需要一些资源来讨论如何将您的软件设计为可扩展的,也就是说,这样其他人就可以编写向其添加功能的附加组件/插件。

你推荐什么?有没有关于这个问题的书?我更喜欢简明扼要的东西;一些理论和一些具体的例子。

我不是针对特定的语言,我希望能够理解核心思想,这样我就可以用任何语言实现它。

出于同样的原因,我不喜欢使用别人构建的框架(除非框架不是很高层次,也就是说,不隐藏太多),目前我只想让自己了解这个主题,并尝试各种方法来实现它。此外,框架通常假定用户了解主题。

更新

我不是在问OOP或者允许我的类被继承。我说的是设计一个将部署在系统上的应用程序,这样它在部署之后就可以通过第三方附加组件进行扩展。

例如,记事本++有一个插件架构,在这个架构中,您可以将一个.dll文件放在插件文件夹中,它向不在该文件夹中的应用程序添加功能,例如颜色选择、代码段插入或许多其他功能(一系列功能)。


如果我们在讨论.NET,请尝试在codeproject上用vbscript编写.NET应用程序脚本。这里有很多具体的例子。

以下是实现各种应用程序扩展技术的站点

    百万千克1ClearScript-使V8、VBScript和JScript可用于.NET应用程序百万千克1百万千克1CS脚本-C脚本引擎百万千克1百万千克1使用C的插件架构#百万千克1百万千克1opinio插件架构百万千克1百万千克1关于Eclipse插件架构的说明百万千克1百万千克1面向初学者的插件架构框架百万千克1百万千克1Gecko插件架构百万千克1百万千克1杀菌剂插件架构百万千克1


OSGi是一个很好的实用的技术框架示例,它允许您做您想要做的事情。

理论就在这里。

(免费!)书在那里。

可扩展性和编写插件的能力必须处理服务生命周期

    百万千克1现场添加/删除服务/插件百万千克1百万千克1管理服务之间的依赖关系百万千克1百万千克1管理服务状态(已声明、已安装、已启动、已停止…)百万千克1

OSGi是干什么的?

One of the main functions of a module is as a unit of deployment… something that we can either build or download and install to extend the functionality of our application.

您将在这里找到一个很好的介绍,介绍服务的中心概念(它与您的问题相关,并解释有关服务的一些问题,可扩展性的关键组件)。

提取:

Why are services then so important if so many applications can be built without them? Well, services are the best known way to decouple software components from each other.

One of the most important aspects of services is that they significantly minimize class loading problems because they work with instances of objects, not with class names. Instances that are created by the provider, not the consumer. The reduction of the complexity is quite surprising

Not only do services minimize configuration, they also significantly reduce the number of shared packages.


在应用程序中实现可靠的原则。

1。单一责任原则:一个类应该只有一个单一的责任(即软件规范中只有一个潜在的变更能够影响该类的规范)

2.打开/关闭原则:软件实体……应打开进行扩展,但关闭进行修改。

三。Liskov替换原则:程序中的对象应可替换为其子类型的实例,而不改变程序的正确性。

4。接口分离原则:多个客户端特定的接口优于一个通用接口

5。依赖倒置原则:依赖抽象。不依赖于具体情况

StackOverflow问题:

单一责任原则示例

打开/关闭原则是个好主意吗?

什么是里斯科夫替代原理?

接口隔离原则-程序到接口

依赖倒置原理是什么?为什么它很重要?


你试图达到两个相互竞争的目标:

百万千克1您的软件的组件必须公开自己的许多组件,以便可以重用它们。百万千克1百万千克1软件的组件必须很少公开它们自己,因此它们可以重用。百万千克1

解释:为了鼓励代码重用,您应该能够扩展现有的类并调用它们的方法。当方法声明为"private"并且类是"final"(并且不能扩展)时,这是不可能的。所以为了实现这个目标,一切都应该是公开的和可访问的。没有私有数据或方法。

当您发布软件的第二个版本时,您会发现版本1的许多想法都是明显错误的。您需要更改许多接口或代码、方法名、删除方法、中断API。如果你这样做,很多人都会拒绝。因此,为了能够开发您的软件,组件不能公开任何不完全必要的东西——以代码重用为代价。

示例:我想观察SWT样式的文本中光标(插入符号)的位置。插入符号不能被扩展。如果您这样做,您会发现代码包含类似"is this class in the package org.eclipse.swt"的检查,并且许多方法都是私有的、最终的,等等。为了实现这个特性,我不得不从SWT中复制大约28个类,因为所有的东西都被锁定了。

SWT是一个很好的框架,可以使用和扩展。


当然,还有著名的开放-关闭原则-http://en.wikipedia.org/wiki/open/closed_原则


这取决于语言。

  • 在C/C++中,我确信有一个Load Loable函数,它允许您在运行时打开一个库并调用它的导出函数。这通常是如何在C/C++中完成的。
  • 在.NET中,有反射,它提供与LoadLibrary相似(但更广泛)的功能。还有一些完整的库是建立在反射之上的,比如托管扩展框架或mono.addins,它们已经为您完成了大部分繁重的工作。
  • 在爪哇,也有反思。还有JPF(Java插件框架),它在Eclipse Irc之类的东西中使用。

根据您使用的语言,我可以推荐一些教程/书籍。我希望这是有帮助的。


写基于插件的应用程序的文章使用一个非常简单的例子清楚地解释了体系结构各个部分的职责;提供了源代码(vb.net)。我发现它对理解基本概念非常有帮助。


因为我没有足够的代表点来发表评论,所以我将此作为答案发布。SharpDevelop是一个用于在C/vb.net/boo中开发应用程序的IDE。它有一个非常令人印象深刻的体系结构,允许它以多种方式进行扩展——从新的菜单项到对整个新语言的开发支持。

它使用一点XML配置来充当IDE核心和插件实现之间的粘合层。它处理插件的定位、加载和版本控制。部署新插件只是简单地复制新的XML配置文件和所需的程序集(DLL)并重新启动应用程序。你可以在原著作者克里斯蒂安·霍尔姆,迈克·克瑞格,伯纳德·斯皮达的《剖析CSharp应用程序》一书中读到更多关于这方面的内容。这本书似乎在那个网站上没有,但我发现一本可能还在附近

在这里也发现了一个相关的问题


如果您使用.NET,我们的研究产生了两种方法:脚本和合成。

脚本编写

通过使用脚本协调类,可以扩展类的功能。这意味着要以动态语言公开用您最喜欢的.NET语言编译的内容。

我们发现一些值得探索的选择:

  • 铁箍龙
  • 铁红的
  • javascript:jint、jurassic和javascript.net是很好的起点。
  • script.net->这是第一个引起我们注意的。

作文

如果您使用.NET 4或更高版本启动一个项目,则必须仔细查看托管扩展性框架(MEF)。它允许您以插件的方式扩展应用程序的功能。

The Managed Extensibility Framework (MEF) is a composition layer for
.NET that improves the flexibility, maintainability and testability of
large applications. MEF can be used for third-party plugin
extensibility, or it can bring the benefits of a loosely-coupled
plugin-like architecture to regular applications.

托管外接程序框架也是一个很好的读物。

  • msdn:http://msdn.microsoft.com/en-us/library/dd460648.aspx
  • codeplex:http://mef.codeplex.com/

插件架构因其可扩展性和灵活性而变得非常流行。

对于C++,Apache HTTPD服务器实际上是基于插件的,但是使用了一个模块的概念。大多数Apache特性都是作为模块实现的,比如缓存、重写、负载平衡,甚至线程模型。它是我见过的一个非常模块化的软件。

对于Java,伊柯丽斯无疑是基于插件的。Eclipse的核心是一个OSGi模块系统,它管理捆绑包,这是插件的另一个概念。bundle可以提供扩展点,我们可以在扩展点上轻松构建模块。OSGi中最复杂的是它的动态特性,这意味着捆绑包可以在运行时安装或卸载。再也不能阻止世界综合症了!


我刚刚开始开发一个智能客户端应用程序。这是我正在考虑的两种选择。

使用Microsoft的System.Addin命名空间。看起来很有希望,但是对于我们的最终解决方案来说可能有点复杂。

或来自Microsoft的智能客户端复合UI应用程序块

最近,我研究了如何同时使用复合UI应用程序块和System.Addin命名空间来构建自己的组件。因为cab有源代码,所以很容易扩展。我认为我们的最终解决方案将是一个重量较轻的驾驶室版本,明确地使用Unity应用程序块


签出"cab"-微软的复合应用程序构建块框架。我想他们也有一个"网络版"…


与其重新发明轮子,不如使用手边的框架。Eclipse和NetBeans都支持基于插件的扩展。不过,你必须在Java中工作。