Polymorphism is very powerful, because it lets old code call new code.<p>But abstraction layers have costs. (Explicitly declared) interfaces are a cost (time to introduce into the system, complexity, lines of code, impedes refactoring).<p>Therefore, don&#x27;t use interfaces (i.e. introduce abstraction layers) until needed (cost is justified).<p>By the way, if you manage to come up with a layer of abstraction that doesn&#x27;t have as much explicit cost, it&#x27;s a cheaper layer of abstraction. So dynamic languages&#x27; &quot;duck typing&quot; feature allows interfaces to emerge gradually, without explicit code to introduce them. Arguably, but IMO, that&#x27;s a better approach.<p>I disagree with the article&#x27;s definition of a leaky interface:
&quot;A Leaky interface exists when the interface is prone to being ignored during any communication between the system and the environment.&quot;<p>A leaky interface is an interface that has non-obvious, non-declared behaviors, and the code <i>has</i> to rely on those behaviors to deliver value&#x2F;functionality.<p>It can be something as simple as an inconsistent implementation that leaks an underlying implementation detail. It doesn&#x27;t mean that the interface is prone to be ignored. In fact, it can be used quite a lot--just in slightly different ways.