Architecture

No Class is an Island

John Sonmez · Jan 5, 2012 · 4 min read

One of the biggest challenges I’ve found with any framework is to make it self-discoverable.  \n\nIt is often difficult to build a framework or API in a way that users of that framework can easily know what exists and when to use what.\n\nOne of the main reasons why it is difficult to write a good framework is that many developers tend to create classes that are very loosely connected to other classes in that framework with which they are intended to interact.\n\n104004A.TIF\n\n

Defining the island

\n\nWhen you create a series of classes, do you explicitly plan for those classes to depend on each other or do you try to design them in a way so that they are independent?\n\nThis question brings up the old topic of loose coupling and tight cohesion.\n\nI consider a class to be an island if it is loosely coupled, but also loosely cohesive.\n\nA class that is an island is a class that does its own thing with very little dependencies or very weak dependencies.\n\nImagine for a moment a CurrencyConverter class.\n\nThis class is designed to take an amount of one currency and convert it to another currency.\n\nThere are several ways we could create the API for this class.\n\nHere is one of them:\n\n

\n\n\n\n

\n\nNow this seems like a pretty reasonable API, but there is a problem here.  The problem is if you have a class that implements ICurrency, you don’t have any good way to know that this class exists.\n\nIf we don’t do anything else, this class might as well not exist at all.  It is an island.\n\nIt can see classes it needs to use, but the classes that could benefit from CurrencyConverter don’t know it exists.\n\nThe developer that is using an ICurrency implementation has no good way to know that this convert exists.  Most likely a developer will end up writing their own implementation of a currency converter.  \n\nDuplication! Bad!\n\n

The date and time link

\n\nYou will often see this in code bases and frameworks.  You will have many different utility folders or classes that help do date and time operations.\n\nThe problem is that no one really knows these utility classes exist and so everyone ends up rewriting the functionality all over your code base and you have a mess.\n\nTake a look at your own project, see if you can find all the utility classes that deal with date, time or currency.  Now check to see if those utility classes are being used everywhere they could be.  Chances are they are not.\n\n

Building bridges

\n\nWe need to build a bridge to the island so that everyone can enjoy the nice beaches.\n\nNo point building your wonderful CurrencyConverter if no one knows it exists, right?\n\nSo how do we solve this problem?\n\nIt definitely is a tricky problem to solve.\n\nThe best way I have found is to tie the dependent class back to its dependency.  \n\nYes, I am advocating circular dependencies!\n\nDon’t be alarmed, it is not that bad.  All you have to do is make sure that your ICurrency interface has a reference to CurrencyConverter so that someone using ICurrency will know it exists.\n\nNow there are many ways of doing this.  Some involve using a base Currency class, others involve creating different static constructors for Currency classes.\n\nI am going to show you a very simple example, just to make my point.\n\n

\n\n\n\n

\n\nIt really is that simple.  You have now built a bridge to the island that was CurrencyConverter.\n\nNow when a developer types ‘.’ on an ICurrency implementation they will see a convert method that uses your converter and they will know it exists!  Joy!\n\nAgain, there are many ways you could build this bridge.  My intention is not to debate them here.\n\nThe point is… BUILD THE BRIDGE!\n\n

But it is a circular dependency, that is bad

\n\nReally?\n\nIt is worse than 5 implementations of currency conversion in your code base?\n\nWhat we have really done here is build something that is extremely tightly cohesive.  This is not necessarily a bad thing.\n\nWhat we don’t want to do is to tightly couple the currency conversion to our billing system code.  We don’t want to have some building system class being used by our CurrencyConverter.\n\n

Applying the idea further

\n\nThe basic idea here is that every time you create a new class you should think about how someone will know it exists.\n\nIf the class is out there on its own and it is likely to be useful in the the future, you must do something to tether it back to its dependencies.\n\nIt is helpful to have the attitude that if a developer can’t discover your class by some other class through intelli-sense, your class might as well not exist.\n\nEvery time I create a class, I try to think of two things:\n\n

    \n

  1. How will someone use this class
  2. \n\n

  3. How will they know this class exists
  4. \n

John Sonmez

John Sonmez

John Sonmez is the founder of Simple Programmer, author of "The Complete Software Developer's Career Guide" and "Soft Skills: The Software Developer's Life Manual." He helps software developers build remarkable careers.