Skip to content

Instantly share code, notes, and snippets.

@SMoni
Last active February 6, 2020 07:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SMoni/6276868 to your computer and use it in GitHub Desktop.
Save SMoni/6276868 to your computer and use it in GitHub Desktop.
List from Zed Shaw (http://zedshaw.com/essays/indirection_is_not_abstraction.html) what an interface should/shouldn't do. Mind his definition of an interface from the original post.

An abstract interface should not require any configuration to use

Configuration should be done behind the scenes using an external resource like a property file, and should be done internally before anyone uses the interface.


An user of an abstract interface should not have to go through more than one function call in a chain to “find” any component they need

Remember that indirection is evil and only ends up adding to the cognitive complexity necessary to use something. You can find examples of this in normal GUIs when you are forced to go through a huge list of complicated steps across multiple interface to complete one task. A wizard is an example of an abstraction over these complicated steps, and it basically provides one access point to your task. The same idea applies to abstract interfaces: If the user has to call more than one function just to access a component or complete a task then you haven’t helped them at all.


If an abstract interface wraps another interface then it should reduce the number of entry points when compared to the interface being wrapped

This is probably the closest to a “measurement” of abstraction as you can get. I sometimes prove the point about abstraction by taking a wrapped interface (the target) and a wrapping supposedly abstract interface (the wrapper). I’ll count the number of functions in the target and the number in the wrapper. If both interfaces have the same number of functions (or worse, the same names) then you haven’t gain anything more than complexity and reduced performance. In this case the interface is not abstract, it is indirect and it should be configurable which implementation gets used.


An abstract interface should not have the goal of being replaceable

If the interface needs to be replaceable then it it should wrap a more complex and configurable interface that is replaceable. This is necessary to avoid confounding the complexity of indirection with the simplicity of an abstraction. Another way to think about this is that abstraction’s simplicity goal competes with how indirection complicates things. It is too difficult balance these competing influences in the same interface so don’t.


If an abstract interface stands alone then it should have a minimum number of entry points necessary to provide its services to others

I shouldn’t have to point this out, but keeping the number of entry points to a minimum makes things simpler. The problem with this is that what is “simpler” and “minimum” depends on the situation and the needs. Usually you’ll start off with a complex interface that is flexible, and then later develop a simpler abstraction around it that encapsulates frequent usage patterns.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment