What Is Loose Coupling?
We all know the big goal is low coupling and high cohesion. But if asked to, could you write down what smells you would see to identify tightly coupled code?
Join the DZone community and get the full member experience.
Join For Free
a couple days ago, i had a developer ask me what it meant to have tightly coupled code and how you detect it.
on tuesday, i saw a similar question on quora asking if there was any tool to analyze layers in application architecture .
because these two subjects relate to each other, i thought i would provide a solid resource (excuse the pun) to explain every aspect of loosely coupled systems.
so where do we begin? how about the obvious?
loose coupling is when two objects can interact with each other but have very limited knowledge about what the other object can do.
while this concept is relatively simple to understand, it's difficult to implement. sometimes you may be under the gun to get a project out the door (hey, you gotta ship it, right?).
some advantages of making your code loosely coupled include:
-
better testability
because your code isn't dependent on other objects and they are just passed in, this makes your unit tests easier to write. -
easy-to-understand code
when your code is decoupled from other objects, they are usually passed in or dependency injected into the code. your code provides a self-documenting service to your users. -
swappable components
while most developers don't think about a plug-in architecture, this is ultimately what developers strive to achieve. if you want to swap out the oracle database component with a sql server component, if developed properly, it can be done easily. -
scalability
as your system grows, you can provide a diverse number of components to plug into your application, making it more scalable. there is a term i use when a system can't scale properly. it's called "painting yourself into a corner" where you need to re-evaluate your design. -
isolated code/features
adding new features to a system means that you can write additional code without breaking existing functionality and feel safe writing it.
but how do you know when a code base has been "tightly wound?"
detecting highly coupled code
not everyone can immediately detect highly coupled code, but there are some quick ways to identify them.
passing in interfaces
one way to identify whether we have a tightly coupled application is that most parameters passed into methods are concrete classes instead of using interfaces. i provide an example below using a customerrepository.
methods "new-ing" up classes
this is a dead giveaway for tightly coupled code. when a piece of code is new-ing up a new class inside a method, this is a code smell.
examine this code for a second.
public void processinsured()
{
var repository = new postrepository();
repository.createrecord();
}
wouldn't it make more sense to initialize the object at the class level or pass it into the method itself?
public void processinsured(irepository repository)
{
repository.createrecord();
}
these are just two that stand out the most.
yet, if we need to examine code across a solution, double-clicking on each class would be time-consuming, so we would need some tools to help us in our coding efforts.
these tools are called static code analyzers. if you aren't a c# developer, don't worry. there are static code analyzers for your language as well.
for .net, there are two that i would recommend.
ndepend
ndepend takes your static code analysis to the next level. it provides a deep-dive into your code and makes you aware of every single dependency in your application.
while it does cost a little bit of money, it provides an elaborate amount of analysis of your code using its own linq language to determine if your code is loosely coupled or not. they have a dependency matrix and general rules for comparing higher cohesion with lower coupling.
i also did a review of ndepend giving it a thumbs-up. it's an absolutely amazing product, and i definitely recommend it.
fxcop
the second static code analysis tool is fxcop .
while this doesn't integrate into visual studio and has its own gui tool, it provides a solid amount of analysis to where you can examine assemblies for dependencies.
it just occurs outside of your ide.
while these two tools are a great help in finding problematic code, we need to focus on how to write loosely couple code.
how to write loosely coupled code
it all starts here. what are some techniques for writing loosely-coupled code?
interfaces
interfaces are probably the easiest way to decouple your code.
examine the following piece of code:
public class customerrepository
{
private readonly dbcontext _context;
public customerrepository(dbcontext context)
{
_context = context;
}
}
the customerrepository has a dependency on a concrete implementation of a dbcontext. this is a tightly coupled example.
it makes more sense to change the code to use interfaces (changes in bold ).
public class customerrepository
{
private readonly idbcontext _context;
public customerrepository(idbcontext context)
{
_context = context;
}
}
public interface idbcontext
{
void savechanges();
}
by making this simple change, we now have the ability to pass in any kind of dbcontext so long as it implements an idbcontext interface. the interface defines the contract but doesn't expect an implementation making it easier to create various dbcontexts that perform different implementations.
dependency injection (di)
whether you use ninject, structuremap, or castle windsor, using any kind of dependency injection framework is a move in the right direction.
while i won't go into a full-on dependency injection tutorial, it's something common most developers are using to write full-featured software and websites.
you've already seen the most simplistic version in the customerrepository example. the code above is often called "poor man's" dependency injection since it passes it in.
if interested in learning more about dependency injection, check out this pluralsight course on dependency injection on-ramp from jeremy clark .
recently, you may have noticed when you start visual studio, it uses yet another type of dependency injection framework called mef (managed extensibility framework) from microsoft. it's intent is to create a plug-in architecture for your application which is another way to decouple your code.
nuget it!
if you have a library of routines, a great exercise is to create and publish a nuget package .
this forces you to examine your code, refactor it, and isolate it into a reusable (or decoupled) package.
web services
i would consider this to be the holy grail of highly decoupled code. you cross domains when making a web service call and receive a loosely typed json object.
web services are just another reason why software is still eating the world .
conclusion
honestly, loose coupling is something that can be taught, but it's harder when you are sitting down and writing code while a deadline is looming over you.
if you want to practice looking over highly coupled code, i would recommend gathering some code katas to give you a better understanding of high cohesion/lower coupling in software development and design.
there is also an enterprise fizzbuzz , which is a sample project showing a number of code no-nos for you to refactor.
Published at DZone with permission of Jonathan Danylko, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments