Coupling Is Your Friend

My SOLID article in Code Magazine talks about the concept of coupling as one of the object oriented principles that we are striving to get right.

Coupling is not inherently evil. If you don’t have some amount of coupling, your software will not do anything for you. You need well-known points of interaction between the pieces of your system. Without them, you cannot create a system of parts that can work together, so you should not strive to eliminate coupling entirely. Rather, your goal in software development should be to attain the correct level of coupling while creating a system that is functional, understandable (readable by humans), and maintainable.” (originally published in the Jan/Feb 2010 issue of CODE Magazine)

I was reminded of this today, during a conversation with some coworkers when we realized that our efforts to decouple several screens from each other had led us to very tightly couple the workflow of the process we were implementing with the screen in that process. Be careful not to miss out on some important modeling opportunities in your efforts to decouple your system. You may end up decoupling the original pieces that you were concerned with only to end up coupling those same pieces to something that should have been made explicit.

In our specific instance we were having problems getting data from one screen to another. Each of our screens was decoupled from the next via calls out to the application controller. For example:

   1: public void Login()

   2: {

   3:     ApplicationController.Execute<Login>();

   4: }

This would open the Login screen from a button click on another screen.

We were having problems figuring out how to get the login information back to the calling screen because the Execute method has no return value. We could have used the event aggregator with the .Raise method on the app controller, but this seems a little hackish. Why should we have to call out to a third party object just to get a return value from should rightfully be a simple method call? In the end we realized that we were so concerned with decoupling the screens from each other that we missed the opportunity to correctly model the processes that we were dealing with. By introducing an object that property encapsulated the process of calling out to the login screen and handling the results of the login effort we were able to resolve the issues, maintain the decoupling between the forms and create a more explicit model and body of knowledge within our code.

   1: public class StartupController()

   2: {

   3:     //pass dependencies in through the constructor, here


   5:     public void Run()

   6:     {

   7:         RunLaunch();

   8:     }


  10:     public void RunLaunch()

  11:     {

  12:         var launchResult = _launch.Run();

  13:         switch (launchResult.Data)

  14:         {

  15:             case LaunchActions.Login:

  16:             {

  17:                 RunLogin();

  18:             }

  19:             //other actions here

  20:         }

  21:     }


  23:     public void RunLogin()

  24:     {

  25:         var loginResult = _login.Run();

  26:         switch (loginResult.Data)

  27:         {

  28:             case LoginActions.Cancel:

  29:             {

  30:                 RunLaunch();

  31:             }

  32:             //other actions here

  33:         }

  34:     }

  35: }

Our efforts to decouple the screens were misguided because we were stuck with the mentality of “decouple this code” when we should have had the mentality of “couple this code correctly”. Once we got past this mental block, though, our problems were easy to solve.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs - the amazingly awesome podcast audio hosting service that everyone should be using, and where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in .NET, AntiPatterns, AppController, C#, Principles and Patterns, Workflow. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Loosely coupled, highly cohesive should be the goal. Not entirely decoupled, but coupled to the right things for the right reasons in the right places where it makes the most sense :)

    See, it’s just that easy :)

  • Good post. I think this is a size of the lego blocks problem.
    I have found with coupling, what we are really trying to achieve is to determine the correct size of the lego blocks we are creating.

    Creating things that are too loosely coupled is akin to creating very small lego blocks, and lots of them. While this isolates change, it can also make it very difficult to build anything.

    Creating things that are too highly coupled is akin to creating 1 or two huge lego blocks. Also not very useful for building anything, and is highly susceptible to any changes.

    Getting the right size of the blocks seems to be the key. I have also found that certain parts of the application, should have different size blocks, if that makes sense.

    You make a good point that not too many are aware of when they toss around words like loose coupling, but highly cohesive.