框架与工具包与图书馆

框架,工具包和图书馆有什么区别?

最重要的区别,实际上库和框架之间的定义差异是控制反转 。

这是什么意思? 那么这就意味着当你打电话给图书馆的时候, 就掌握了。 但是对于一个框架,控制是相反的: 框架调用你。 (这就是所谓的好莱坞原则:不要打电话给我们,我们会打电话给你。)这几乎是一个框架的定义。 如果它没有控制反转,那不是一个框架。 (我在看你,.NET!)

基本上,所有的控制stream程已经在框架中,并且只有一堆预定义的白点可以用你的代码填写。

另一方面,库是可以调用的function集合。

我不知道这个术语工具箱是否真的很好定义。 只是“kit”这个词似乎暗示着某种模块化,即一组独立的库,你可以从中select。 那么,什么使得工具包不同于一堆独立的库呢? 整合:如果你只有一堆独立的库,不能保证它们能够很好地协同工作,而工具包中的库被devise成可以很好地协同工作 – 你不必全部使用它们。

但这只是我对这个术语的解释。 与定义明确的图书馆和框架不同,我不认为工具箱有一个被广泛接受的定义。

马丁·福勒(Martin Fowler)在他关于控制反转的文章中讨论了图书馆和框架之间的区别:

控制反转是使框架与图书馆不同的一个关键部分。 图书馆本质上是一组你可以调用的函数 ,这些函数通常组织成类。 每个调用都会做一些工作,并将控制权返回给客户端。

框架体现了一些抽象devise,内置了更多的行为。为了使用它,您需要通过子类化或插入自己的类来将您的行为插入框架中的各个位置框架的代码然后在这些地方调用你的代码

总结一下:你的代码调用一个库,但是一个框架调用你的代码。

介绍

关于相关代码的集合有各种各样的术语,它们既有历史(在这个答案的目的之前是1994年5月5日)以及当前的含义,读者应该知道这两者,特别是在阅读关于计算/编程的经典文本时从历史的时代。

图书馆

在历史上和现在,图书馆都是与特定任务相关的代码集合,或者是在大致相同的抽象层次上运行的一组密切相关的任务。 它通常缺乏自己的任何目的或意图,并打算被(消费)使用并与客户端代码集成以帮助客户端代码执行任务。

工具包

从历史上看,工具包是一个更加专注的库,具有明确的目的。 目前,这个术语已经不受青睐,几乎完全(据笔者所知)用于当前时代的graphics小部件和GUI组件。 一个工具包通常会比一个库在一个更高的抽象层上运行,并且经常会消耗和使用库本身。 与库不同,工具箱代码经常被用来执行客户代码的任务,例如构build窗口,调整窗口大小等。工具箱中抽象的较低级别是固定的,或者可以由客户自己操作代码以被禁止的方式。 (Think Window风格,可以是固定的,或者可以通过客户端代码预先更改的。

骨架

历史上,框架是一套相互关联的库和模块,分为“一般”或“特定”类别。 通用框架旨在通过提供通用function(如跨平台内存pipe理,multithreading抽象,dynamic结构(以及通用的通用结构))来为构build应用程序提供全面的集成平台。 历史通用框架(没有dependency injection,见下文)几乎普遍被OO语言(如STL for C ++)的多态模板化(参数化)打包语言产品或非OO语言的打包库所取代(保证Solaris C头文件)。 通用框架运行在不同层次的抽象层次上,但普遍处于较低层次,像图书馆一样依靠客户端代码在他们的协助下执行特定的任务。

历史上,“特定”框架是为单一的(但通常是庞大的)任务而开发的,比如用于工业系统的“命令和控制”系统,以及早期的networking堆栈,并且在高度抽象的层面上运行,像工具包一样被用来执行的客户端代码任务。

目前,框架的定义越来越侧重于其他地方提到的“控制反转”原则,作为指导原则,程序stream程以及框架执行。 然而框架仍然针对特定的输出。 例如特定操作系统的应用程序(例如用于MS Windows的MFC),或者用于更通用的工作(例如Spring框架)。

SDK:“软件开发工具包”

SDK是帮助程序员创build和部署代码/内容的工具集合,这些代码/内容非常专门针对在非常特定的平台上运行或以特定的方式运行。 一个SDK可以由一组库组成,这些库只能通过客户端代码以特定方式使用,并且可以正常编译,最多只能创build或修改二进制资源以生成二进制资源(SDK )输出。

发动机

引擎(代码集合术语)是一个二进制文件,它将以某种方式运行定制的内容或过程input数据。 游戏和graphics引擎也许是这个术语中最主要的用户,几乎被普遍使用在SDK中来定位引擎本身,例如UDK(虚幻开发工具包),但也存在其他引擎,例如search引擎和RDBMS引擎。

一个引擎经常(但并不总是)只允许其内部的一些内部对其客户是可访问的。 大多数情况下,要么是针对不同的体系结构,要么改变引擎的输出显示,要么为了调整目的。 开源引擎在定义上向客户开放以根据需要进行更改和更改,并且一些专有引擎被完全固定。 世界上最常用的引擎,几乎可以肯定是Javascript引擎。 embedded到每个浏览器的地方,都有一大堆的JavaScript引擎,将JavaScript作为input,处理它,然后输出到渲染。

API:“应用程序编程接口”

我正在回答的最后一个术语是我个人的怪胎:API,历史上用于描述应用程序或环境的外部接口,它本身能够独立运行,或者至less在没有任何必要的客户端干预的情况下执行它的任务在初始执行之后。 诸如数据库,文字处理器和Windows系统等应用程序会将一组固定的内部钩子或对象暴露给客户可以调用/修改/使用等的外部接口,以执行原始应用程序可以执行的function。 API通过API提供了多lessfunction,而且客户端代码还使用了多less核心应用程序。 (例如,一个文字处理API可能需要完整的应用程序在客户端代码的每个实例运行时被后台加载,或者可能只是其中一个链接库;而正在运行的窗口系统将创build内部对象以由其自身进行pipe理将代码传递回客户端代码来代替。

目前,术语“API”的范围更广泛,通常用于描述此答案中的几乎所有其他术语。 实际上,应用于这个术语的最常见的定义是,API为另一个软件(API的客户端代码)提供了一个约定的外部接口。 实际上,这意味着一个API是依赖于语言的,并且具有由上述代码集合之一提供的具体实现,诸如库,工具箱或框架。 例如,看一个特定的区域,协议,API与协议是不同的,协议是代表一组规则的更通用的术语,然而,特定协议/协议套件的单独实现将外部接口暴露给其他软件通常会被称为API。

备注

如上所述,上述术语的历史和现在的定义已经发生了变化,这可以被看作是对基础计算原理和范例的科学理解的提高,以及软件特定模式的出现。 特别是九十年代早期的GUI和Windowing系统帮助定义了许多这些术语,但是由于OS Kernel和Windowing系统为批量cunsumer操作系统(bar或者Linux)的有效混合,以及大规模采用dependency injection/控制作为一种消费图书馆和框架的机制的倒置,这些条款必须改变它们各自的含义。


PS(一年后)

在仔细思考这个问题一年以上之后,我拒绝将IoC原则作为框架与图书馆之间的定义区别。 有大量的受欢迎作者说这是,但是几乎有相同数量的人说这不是。 那里有太多的“框架”,不会使用IoC来说明它是定义原则。 embedded式或微控制器框架的search揭示了一大堆不使用IoC的现象,我现在认为.Net语言和CLR是“一般”框架的可接受的后代。 如果说IoC是决定性的特征,我恐怕只是过于僵化而不能接受,而把任何事物作为一个与上述历史表征相匹配的框架来拒绝。

有关非IoC框架的详细信息,请参阅上面提到的许多embedded式和微型框架,以及不通过语言提供callback的语言中的任何历史框架(可以使用任何具有现代注册系统,但不是一般的程序员),显然,.NET框架。

如果你是一个更直观的学习者,这里有一些图表明确说明:

(学分: http : //tom.lokhorst.eu/2010/09/why-libraries-are-better-than-frameworks )

Menzani和Barrass提供的答案可能是最完整的。 不过,这个解释可以很容易地说清楚。 大多数人都错过了这些都是嵌套的概念。 所以让我把它摆在你身边。

编写代码时:

  • 最终你会发现你在程序中重复的代码段,所以你可以将它们重构成函数/方法
  • 最终,在写了几个程序之后,你发现自己已经把你已经做的function复制到了新的程序中。 为了节省您的时间,将这些函数捆绑到库中
  • 最终你会发现自己每次使用某些库时都会创build相同types的用户界面。 所以你重构你的工作,创build一个工具包 ,允许你从generics的方法调用中更容易地创build你的UI。
  • 最终,你已经写了这么多的应用程序,使用相同的工具包和库,你创build了一个框架 ,已经提供了这个样板代码的通用版本,所以你所需要做的就是devise界面的外观和处理事件来自用户交互。

一般来说,这完全解释了术语之间的差异。

一个库只是一个包装成一个包的方法/函数的集合,可以导入一个代码项目并重用。

框架是一个强大的库或库的集合,为您的代码提供“基础”。 一个框架遵循控制反转模式。 例如,.NET框架是一个大型的内聚库集合,您可以在其中构build您的应用程序。 你可以争辩说框架和图书馆之间没有太大的区别,但是当人们说“框架”的时候,它通常意味着一个更大,更强大的库的组合,它将扮演一个应用程序的一个组成部分。

我想像一个工具包,就像我想到一个SDK一样。 它带有文档,例子,库,包装器等。同样,你可以说这和框架是一样的,你可能会这样做。

它们几乎都可以互换使用。

非常非常相似,一个框架通常是一个更加完善和完善的图书馆,而一个工具箱可以简单地成为一个类似的图书馆和框架的集合。

这是一个很好的问题,甚至可能是主观的,但我相信这是我能给出的最好答案。

图书馆

我认为一个图书馆是代码已经编码,你可以使用,以便不必再次编码。 代码的组织方式可以让你查看你想要的function,并从你自己的代码中使用它。

大多数编程语言都带有标准库,尤其是一些实现某种集合的代码。 这总是为了方便,你不必自己编写这些东西。 同样,大多数编程语言的构造允许您从库中查找function,例如dynamic链接,命名空间等。

因此,经常需要重用的代码是放在库中的好代码。

工具包

一套用于特定目的的工具。 这是一致的。 问题是,什么被视为一种工具,什么不是。 我会说没有固定的定义,它取决于自称为工具包的东西的上下文。 工具的例子可以是库,小部件,脚本,程序,编辑器,文档,服务器,debugging器等。

另外要注意的是“特定目的”。 这总是正确的,但是目标的范围很容易根据谁来制作工具包而改变。 所以它可以很容易地成为程序员的工具包,或者它可以是一个stringparsing工具包。 一个是如此广泛,它可以有工具触摸所有相关的编程,而另一个更精确。

软件开发工具包通常是工具包,因为他们尝试将一组工具(通常是多种)捆绑到一个软件包中。

我认为一个共同的思路是,一个工具可以完全为你做些事情,或者帮助你做到这一点。 而工具包就是一组工具,它们都可以执行或帮助您执行特定的一组活动。

骨架

框架不是一致的定义。 对于任何可以构build代码的东西来说,这似乎都是一个总括的术语。 这将意味着:任何基础或支持你的代码的结构。

这意味着你可以根据框架构build你的代码,而你可以根据你的代码构build一个库。

但是,有时框架这个词似乎和工具包甚至图书馆一样。 .Net框架大多是一个工具包,因为它是由作为库的FCL和作为虚拟机的CLR组成的。 所以你会认为它是Windows上C#开发的工具包。 Mono是Linux上用于C#开发的工具包。 但他们称之为框架。 这样做也是有道理的,因为这种方式可以使你的代码框架化,但是一个框架应该更多地支持和把握事物,然后做任何工作,所以我认为这不是你应该使用的方式字。

而且我认为业界正试图进入框架,意味着已经编写了一个程序,缺less必须提供或定制的部分。 我认为这是一件好事,因为工具包和库对于“框架”的其他用法来说是非常精确的术语。

框架:安装在你的机器上,并允许你与它进行交互。 没有框架,你不能发送编程命令到你的机器

图书馆:旨在解决某个问题(或与同类问题有关的几个问题)

工具包:许多代码的集合,可以解决多个问题的多个问题(就像一个工具箱)

我觉得这有点主观。 该工具包是最简单的。 这只是一堆方法,可以使用的类。
图书馆vs框架问题,我使用它们的方式有所不同。 我很久以前就读过一个完美的答案。 框架调用你的代码,但另一方面你的代码调用库。

关于Mittag的正确答案:

一个简单的例子。 假设您在其中一个类中实现了ISerializable接口(.Net)。 那么你就可以利用.Net的框架特性 ,而不是它的图书馆特质。 你填写“白点”(如mittag说),你已经完成了骨架。 您必须事先知道框架将如何与您的代码“作出反应”。 实际上,.net是一个框架,在这里我不同意Mittag的观点。

在本书的第19章(整章专门讨论这个主题)中,对你的问题给出了完整的,完整的答案 , 这本书是非常好的一本书 (根本不是“仅仅是为了Smalltalk”)。

其他人已经注意到.net可能既是一个框架,一个库和一个工具包,取决于你使用的是哪一个部分,但也许是一个例子的帮助。 处理数据库的entity framework是使用控制模式反转的.net的一部分。 你让它知道你的模型,它会计算出如何处理它们。 作为一个程序员,它需要你理解“框架的思想”,或者更真实地理解devise者的思想以及他们将如何处理你的投入。 另一方面,数据读取器和相关的调用只是一个工具,可以将数据从表格/视图中提取出来并提供给您。 它永远不会理解如何采取父母的孩子关系,并将其从对象转换为关系,你会使用多个工具来做到这一点。 但是,如果要存储数据,交易时间等,您将拥有更多的控制权。