Understand tightly coupled code

Completed

Tightly coupled code occurs when components are overly dependent on each other's implementation details. The dependency can make your code harder to maintain, less flexible, and more prone to bugs. A common solution is to use interfaces to decouple components and improve modularity.

In your role as a software developer, you encounter the challenges of tightly coupled code in where there's a direct dependency. You apply the Open/Closed Principle to address decoupling your code for building a more maintainable system.

Tightly coupled code

Tightly coupled code refers to a situation where one component is heavily reliant on the internal details of another. This creates a rigid system that is difficult to modify or extend without breaking existing functionality.

Direct dependency example

Consider a Library class that directly interacts with a BorrowableBook class. The Library class depends on the specific implementation of BorrowableBook to perform borrowing operations.

public class BorrowableBook
{
    public string Title { get; set; }
    public bool IsAvailable { get; private set; } = true;

    public BorrowableBook(string title)
    {
        Title = title;
    }

    public void Borrow()
    {
        if (IsAvailable)
        {
            IsAvailable = false;
            Console.WriteLine($"You have borrowed \"{Title}\".");
        }
        else
        {
            Console.WriteLine($"\"{Title}\" is already borrowed.");
        }
    }
}

public class Library
{
    private BorrowableBook _book;

    public Library(BorrowableBook book)
    {
        _book = book;
    }

    public void BorrowBook()
    {
        if (_book.IsAvailable)
        {
            _book.Borrow();
        }
        else
        {
            Console.WriteLine("The book is not available.");
        }
    }
}

In this code, the Library class depends directly on the BorrowableBook class. While the dependency works for a single type of borrowable item, it introduces two key issues:

  • Direct Dependency: The Library class is tightly coupled to the BorrowableBook type. If you want to add new borrowable items (for example, DVDs, magazines), you would need to modify the Library class.
  • Limited Extensibility: The current design makes it difficult to extend functionality without changing existing code.

This tight coupling violates the Open/Closed Principle (OCP), which states that software should be open for extension but closed for modification. In other words, you should be able to add new features without altering existing code.

By reducing dependencies, you can:

  • Improve Maintainability: Changes in one part of the system are less likely to affect others.
  • Enhance Flexibility: New features can be added without modifying existing code.
  • Simplify Testing: Components can be tested independently.

To address the issue, you need to refactor the code using interfaces to make it more modular and flexible.