A shim is some code that takes care of what's asked (by 'interception'), without anyone being any wiser about it.
Example of a Shim
An example of a shim would be rbenv (a ruby tool). Calls to ruby commands are "shimmed". i.e. when you run bundle install, rbenv intercepts that message, and reroutes it according to the specific version of Ruby you are running. If that doesn't make sense try this example, or just think of the fairy god mother intercepting messages and delivering apposite outcomes.
That's it!
Important Clarifications on this example
Note: Like most analogies, this is not perfect: usually Ralph will get EXACTLY what he asked for - but the mechanics of HOW it was obtained is something Ralph doesn't care about. If Ralph asks for dog food, a good shim will deliver dog food.
I wanted to avoid semantic arguments etc. Here's my thinking: talking about adapter, facade, proxy, gang of four patterns - too much conceptual complexity. Introducing code? Pedagogically risky without a conceptual foundation. Encyclopedia / dictionary explanation? Boring, complex, time consuming to read - usually without a use-case. So I simplified it to a cartoon: hoping you can quickly / easily understand in a "fun" way and move on - if you prefer an academic definition, consider the Wikipedia entry on shims 1.
1 Coz I get complaints about the analogies. I'm like... ¯¯\(ツ)/¯¯ it takes time to create the concept, find the photos, photo-shop this stuff, to make it 'fun', and it was never intended to be a picture perfect scientific / academic definition.
The term "shim" as defined in Wikipedia would technically be classified, based on its definition, as a "Structural" design pattern. The many types of “Structural” design patterns are quite clearly described in the (some would say defacto) object oriented software design patterns reference "Design Patterns, Elements of Reusable Object-Oriented Software" better known as the "Gang of Four".
The "Gang of Four" text outlines at least 3 well established patterns known as, "Proxy", "Adapter" and "Facade" which all provide “shim” type functionality. In most fields it’s often times the use and or miss use of different acronyms for the same root concept that causes people confusion. Using the word “shim” to describe the more specific “Structural” design patterns "Proxy", "Adapter" and "Facade" certainly is a clear example of this type of situation. A "shim" is simply a more general term for the more specific types of "Structural" patterns "Proxy", "Adapter", "Facade" and possibly others.
It’s a metaphor based on the English language word shim, which is an
engineering term used to describe a piece of wood or metal that is
inserted between two objects to make them fit together better. In
computer programming, a shim is a small library which transparently
intercepts an API, changes the parameters passed, handles the
operation itself, or redirects the operation elsewhere. Shims can also
be used for running programs on different software platforms than they
were developed for.
So a shim is a generic term for any library of code that acts as a middleman and partially or completely changes the behavior or operation of a program. Like a true middleman, it can affect the data passed to that program, or affect the data returned from that program.
The Windows API is an example:
The application is generally unaware that the request is going to a
shim DLL instead of to Windows itself, and Windows is unaware that the
request is coming from a source other than the application (because
the shim DLL is just another DLL inside the application’s process).
So the two programs that make the "bread" of the "shim sandwich" should not be able to differentiate between talking to their counterpart program and talking to the shim.
What are some pros and cons of using shims?
Again, from the article:
You can fix applications without access to the source code, or without
changing them at all. You incur a minimal amount of additional
management overhead... and you can fix a
reasonable number of applications this way. The downside is support as
most vendors don’t support shimmed applications. You can’t fix every
application using shims. Most people typically consider shims for
applications where the vendor is out of business, the software isn’t
strategic enough to necessitate support, or they just want to buy some
time.
noun
a washer or thin strip of material used to align parts,
make them fit, or reduce wear.
verb ( shimmed, shimming) [ trans. ]
wedge (something) or fill up (a space) with a shim.
ORIGIN early 18th cent.: of unknown origin
这似乎与网页设计师使用这个词的方式非常吻合。
As for origins of the word, quoth Apple's Dictionary widget
noun
a washer or thin strip of material used to align parts,
make them fit, or reduce wear.
verb ( shimmed, shimming) [ trans. ]
wedge (something) or fill up (a space) with a shim.
ORIGIN early 18th cent.: of unknown origin
This seems to fit quite well with how web designers use the term.
As we could see in many responses here, a shim is a sort of adapter that provides functionality at API level which was not necessarily part of that API. This thread has a lot of good and complete responses, so I'm not expanding the definition further.
Javascript has evolved a lot during the last few years, and among many other changes to the language specification, a lot of new methods have been added to its core objects.
For example, in the ES2015 specification (aka ES5), the method find has been added to the Array prototype. So let's say you are running your code using a JavasScript engine prior to this specification (ex: Node 0.12) which doesn't offer that method yet. By loading the ES5 shim, these new methods will be added to the Array prototype, allowing you to make use of them even if you are not running on a newer JavaScript specification.
You might ask: why would someone do that instead of upgrading the environment to a newer version (let's say Node 8)?
There is a lot of real cases scenarios where that approach makes sense. One good example:
Let's say you have a legacy system that is running in an old environment, and you need to use such new methods to implement/fix a functionality. The upgrade of your environment still a work in progress because there are compatibility issues that require a lot of code changes and tests (a critical component).
In this example, you could try to craft your own version of such functionality, but that would make your code harder to read, more complex, can introduce new bugs and will require tons of additional tests just to cover a functionality that you know it will be available in the next release.
Instead, you can use this shim and make use of these new methods, taking advantage of the fact that this fix/functionality will be compatible after the upgrade, because you are already using the methods known to be available in the next specification. And there is a bonus reason: since these methods are native to the next language specification, there is a good chance that they will run faster than any implementation that you could have done if you tried to make your own version.
Another real scenario where such approach is welcome is at browser level. Let's say you need to support old browser and want to take advantage of these newer features. Javascript is a language that allows you to add/modify methods in its core objects (like adding methods to Array prototype), and those shim libraries are smart enough to add such methods only if the current implementation is lacking of them.
PS:
1) You will see the term "Polyfill" related to these Javascript shims. Polyfill is a more specialized type of shim that is used to provide forward compatibility in different browser level specifications. By the way, my example above refers exactly to such example.
2) Shims are not limited to this example (adding functionality that will be available in a future release). There are different use cases that would be considered to be a shim as well.
3) If you are curious about how this specific polyfill is implemented, you can open Javascript Array.find specs and scroll to the end of the page where you will find a canonical implementation for this method.
client app(v1) -> server A (returns a response itself)
Now you have a fancier server named B. You want to get rid of server A. What do you?
August
client app(v2) -> server B (returns response)
client app(v1) -> server A (returns response)
Can you turn down server A?
You can't! Because older builds of your mobile application are still in use. What should you do then?
December (turn server A into a shim)
client app (v1) -> server A - > server B -> server A
client app (v2) - > server B
You make the change at the servers. Basically server A no longer acts as like a real server. It's a fake front. You have to keep it around because you can't magically update the URL an old installed app on someone's phone who hasn't updated their app.
This fake front is what's known as a shim.
What advantage does the shim offer?
The platform team and client teams can deprecate a server on their own separate schedules.
You can stop development on the older server. Because all it does is relay things to the new server.
Can you turn off server A?
No. Because it’s still called by old apps. You can only turn it off if you forced your users to a newer app version.
SHIM is another level of security check which is done for all the services, to protect upstream systems. SHIM Server validates every incoming request, with Headers User credentials, against the user credentials, which are passed in the request(SOAP / RESTFUL).
发布评论
评论(8)
通过卡通进行简单解释
总结
垫片是一些代码,它负责处理所请求的内容(通过“拦截”),而没有人对此有任何了解。
填充程序示例
填充程序的示例是 rbenv(
ruby
工具)。对 ruby 命令的调用是“shimmed”的。即,当您运行bundle install
时,rbenv 会拦截该消息,并根据您正在运行的特定 Ruby 版本重新路由它。如果这没有意义尝试这个例子,或者想象一下仙女妈妈拦截消息并提供适当的结果。就是这样!
关于此示例的重要说明
1 因为我收到了关于类比的抱怨。我想... ́́\(ツ)/́́ 需要时间来创建概念,找到照片,对这些东西进行后期处理,使其变得“有趣”,而且它从来没有打算成为一个完美的科学/学术定义。
Simple Explanation via Cartoon
Summary
A shim is some code that takes care of what's asked (by 'interception'), without anyone being any wiser about it.
Example of a Shim
An example of a shim would be rbenv (a
ruby
tool). Calls to ruby commands are "shimmed". i.e. when you runbundle install
, rbenv intercepts that message, and reroutes it according to the specific version of Ruby you are running. If that doesn't make sense try this example, or just think of the fairy god mother intercepting messages and delivering apposite outcomes.That's it!
Important Clarifications on this example
1 Coz I get complaints about the analogies. I'm like... ¯¯\(ツ)/¯¯ it takes time to create the concept, find the photos, photo-shop this stuff, to make it 'fun', and it was never intended to be a picture perfect scientific / academic definition.
维基百科中定义的术语“shim”在技术上根据其定义被分类为“结构”设计模式。许多类型的“结构”设计模式在(有些人会说事实上)面向对象的软件设计模式参考中非常清楚地描述了“设计模式,可重用面向对象软件的元素” 更广为人知的名称是“Gang of四”。
“四人帮” 文本概述了至少 3 个成熟的模式,称为“代理”, “Adapter”和“Facade”都提供“shim”类型的功能。在大多数领域中,经常会使用或错过使用同一根概念的不同缩写词,从而导致人们感到困惑。使用“shim”一词来描述更具体的“结构”设计模式“代理”, "适配器" 和 "Facade" 无疑是这种情况的一个明显例子。 “垫片”只是更具体类型的“结构”模式“代理”、“适配器”、“外观”以及可能的其他类型的更通用术语。
The term "shim" as defined in Wikipedia would technically be classified, based on its definition, as a "Structural" design pattern. The many types of “Structural” design patterns are quite clearly described in the (some would say defacto) object oriented software design patterns reference "Design Patterns, Elements of Reusable Object-Oriented Software" better known as the "Gang of Four".
The "Gang of Four" text outlines at least 3 well established patterns known as, "Proxy", "Adapter" and "Facade" which all provide “shim” type functionality. In most fields it’s often times the use and or miss use of different acronyms for the same root concept that causes people confusion. Using the word “shim” to describe the more specific “Structural” design patterns "Proxy", "Adapter" and "Facade" certainly is a clear example of this type of situation. A "shim" is simply a more general term for the more specific types of "Structural" patterns "Proxy", "Adapter", "Facade" and possibly others.
根据微软的文章 “揭秘垫片”:
因此,填充程序是任何充当中间人并部分或完全改变程序的行为或操作的代码库的通用术语。就像真正的中间人一样,它可以影响传递给该程序的数据,或影响从该程序返回的数据。
Windows API 是一个示例:
因此,制作“垫片三明治”的“面包”的两个程序不应该能够区分与对应程序交谈和与垫片交谈。
使用垫片有哪些优点和缺点?
同样,来自文章:
According to Microsoft's article "Demystifying Shims":
So a shim is a generic term for any library of code that acts as a middleman and partially or completely changes the behavior or operation of a program. Like a true middleman, it can affect the data passed to that program, or affect the data returned from that program.
The Windows API is an example:
So the two programs that make the "bread" of the "shim sandwich" should not be able to differentiate between talking to their counterpart program and talking to the shim.
What are some pros and cons of using shims?
Again, from the article:
至于这个词的起源,引用苹果词典小部件的说法,
这似乎与网页设计师使用这个词的方式非常吻合。
As for origins of the word, quoth Apple's Dictionary widget
This seems to fit quite well with how web designers use the term.
.net 4.5 Microsoft Fakes 框架中使用垫片将您的应用程序与单元的其他程序集隔离测试。垫片将对特定方法的调用转移到您在测试中编写的代码
Shims are used in .net 4.5 Microsoft Fakes framework to isolate your application from other assemblies for unit testing. Shims divert calls to specific methods to code that you write as part of your test
正如我们在此处的许多响应中看到的,填充程序是一种适配器,它提供 API 级别的功能,但不一定是该 API 的一部分。这个帖子有很多好的、完整的回复,所以我不会进一步扩展这个定义。
不过,我想我可以添加一个很好的例子,那就是 Javascript ES5 Shim (https://github .com/es-shims/es5-shim):
Javascript 在过去几年中已经发展了很多,除了语言规范的许多其他更改之外,还向其核心对象添加了许多新方法。
例如,在 ES2015 规范(又名 ES5)中,方法
find
已添加到Array
原型中。假设您正在使用此规范之前的 JavasScript 引擎(例如:Node 0.12)运行代码,但该规范尚未提供该方法。通过加载 ES5 shim,这些新方法将被添加到 Array 原型中,即使您没有在较新的 JavaScript 规范上运行,也可以使用它们。您可能会问:为什么有人会这样做,而不是将环境升级到较新的版本(假设是 Node 8)?
在很多真实的案例中,这种方法都是有意义的。一个很好的例子:
假设您有一个在旧环境中运行的遗留系统,并且您需要使用此类新方法来实现/修复功能。您的环境升级仍在进行中,因为存在兼容性问题,需要大量代码更改和测试(关键组件)。
在此示例中,您可以尝试制作自己的此类功能版本,但这将使您的代码更难以阅读、更复杂,可能会引入新的错误,并且需要大量额外的测试才能覆盖您知道会出现的功能。将在下一个版本中提供。
相反,您可以使用此填充程序并利用这些新方法,利用此修复/功能在升级后兼容的事实,因为您已经在使用下一个规范中已知可用的方法。还有一个额外的原因:由于这些方法是下一个语言规范的本机,因此它们很有可能比您尝试制作自己的版本时可以完成的任何实现运行得更快。
这种方法受欢迎的另一个真实场景是在浏览器级别。假设您需要支持旧版浏览器并希望利用这些新功能。 Javascript 是一种允许您在其核心对象中添加/修改方法的语言(例如向数组原型添加方法),并且这些填充库足够智能,仅在当前实现缺少这些方法时才添加这些方法。
附:
1) 您将看到与这些 Javascript shim 相关的术语“Polyfill”。 Polyfill 是一种更专业的填充程序,用于在不同的浏览器级别规范中提供向前兼容性。顺便说一句,我上面的例子正是指这样的例子。
2) 垫片不限于此示例(添加将在未来版本中提供的功能)。有不同的用例也被视为垫片。
3)如果你好奇这个特定的polyfill是如何实现的,你可以打开Javascript Array.find 规范并滚动到页面末尾,您将在其中找到此方法的规范实现。
As we could see in many responses here, a shim is a sort of adapter that provides functionality at API level which was not necessarily part of that API. This thread has a lot of good and complete responses, so I'm not expanding the definition further.
However, I think I can add a good example, which is the Javascript ES5 Shim (https://github.com/es-shims/es5-shim):
Javascript has evolved a lot during the last few years, and among many other changes to the language specification, a lot of new methods have been added to its core objects.
For example, in the ES2015 specification (aka ES5), the method
find
has been added to theArray
prototype. So let's say you are running your code using a JavasScript engine prior to this specification (ex: Node 0.12) which doesn't offer that method yet. By loading the ES5 shim, these new methods will be added to theArray
prototype, allowing you to make use of them even if you are not running on a newer JavaScript specification.You might ask: why would someone do that instead of upgrading the environment to a newer version (let's say Node 8)?
There is a lot of real cases scenarios where that approach makes sense. One good example:
Let's say you have a legacy system that is running in an old environment, and you need to use such new methods to implement/fix a functionality. The upgrade of your environment still a work in progress because there are compatibility issues that require a lot of code changes and tests (a critical component).
In this example, you could try to craft your own version of such functionality, but that would make your code harder to read, more complex, can introduce new bugs and will require tons of additional tests just to cover a functionality that you know it will be available in the next release.
Instead, you can use this shim and make use of these new methods, taking advantage of the fact that this fix/functionality will be compatible after the upgrade, because you are already using the methods known to be available in the next specification. And there is a bonus reason: since these methods are native to the next language specification, there is a good chance that they will run faster than any implementation that you could have done if you tried to make your own version.
Another real scenario where such approach is welcome is at browser level. Let's say you need to support old browser and want to take advantage of these newer features. Javascript is a language that allows you to add/modify methods in its core objects (like adding methods to Array prototype), and those shim libraries are smart enough to add such methods only if the current implementation is lacking of them.
PS:
1) You will see the term "Polyfill" related to these Javascript shims. Polyfill is a more specialized type of shim that is used to provide forward compatibility in different browser level specifications. By the way, my example above refers exactly to such example.
2) Shims are not limited to this example (adding functionality that will be available in a future release). There are different use cases that would be considered to be a shim as well.
3) If you are curious about how this specific polyfill is implemented, you can open Javascript Array.find specs and scroll to the end of the page where you will find a canonical implementation for this method.
当前设置:
Jan
现在你有一个名为 B 的更高级的服务器。你想摆脱服务器 A。你会怎么做?
August
你能拒绝服务器 A 吗?
你不能!因为您的移动应用程序的旧版本仍在使用中。那你该怎么办?
12 月(将服务器 A 变成垫片)
您在服务器上进行更改。基本上,服务器 A 不再像真正的服务器一样运行。前面是假的。您必须保留它,因为您无法神奇地更新尚未更新应用程序的手机上旧安装的应用程序的 URL。
这个假冒的前端就是所谓的填充程序。
填充程序提供什么优势?
你能关闭服务器A吗?
不。因为它仍然被旧应用程序调用。仅当您强制用户使用较新的应用程序版本时,您才能将其关闭。
Current setup:
Jan
Now you have a fancier server named B. You want to get rid of server A. What do you?
August
Can you turn down server A?
You can't! Because older builds of your mobile application are still in use. What should you do then?
December (turn server A into a shim)
You make the change at the servers. Basically server A no longer acts as like a real server. It's a fake front. You have to keep it around because you can't magically update the URL an old installed app on someone's phone who hasn't updated their app.
This fake front is what's known as a shim.
What advantage does the shim offer?
Can you turn off server A?
No. Because it’s still called by old apps. You can only turn it off if you forced your users to a newer app version.
SHIM 是对所有服务进行的另一级别的安全检查,以保护上游系统。 SHIM 服务器根据请求中传递的用户凭据(SOAP / RESTFUL),使用标头用户凭据验证每个传入请求。
SHIM is another level of security check which is done for all the services, to protect upstream systems. SHIM Server validates every incoming request, with Headers User credentials, against the user credentials, which are passed in the request(SOAP / RESTFUL).