Question

When designing an application, when do you know that your objects are tightly coupled? What are the symptomps of tightly coupled objects/codes?

Était-ce utile?

La solution

Lets take two objects A & B:

For the sake of simplicity lets asume that A has the following properties

Name: String Age: Integer DateOfBirth: DateTime

B has the following method:

CreateInstanceOfA(string Name, Integer Age, Datetime DateOfBirth) and returns an instance of A with its values initialized to the method arguments.

Now, suppose you add a new property to A:

StateCode: string

Now you have a problem. Do you update the CreateInstanceOfA to include the new property? If so, you have to change the code everywhere it's referenced to include the new field. If your language of choice supports operator overloading you can add a new method. It may not break compilation, but you still have to update the code. Even worse, you would use the old method and would have to manually set the new property after creation.

Son A & B are really tightly coupled.

It's not the best example but it's a quick way of seeing the possible ramifications of a change in a design

Autres conseils

A rule of thumb would be to count how many other classes a given class refers to. There are several ways to look at this:

  • Number of imports (Java), usings (C#), includes (C++) etc.
  • Number of fields / member variables in a class
  • Number of parameters to a method
  • Number of indirect type references (eg. a.getB().getC().getD())

A change to any of these types would potentially cause the tightly coupled class to also change.

You know that your design is tightly coupled when a small change in your design affects a large number of (possible unrelated to your change) classes.

Class D is a class that provides some functionality to other classes.
Class A, Class B and Class C use it directly.
Any change in D can affect A, B and C.
Now suppose we want to enhance D to authenticate any action coming from class A. Not possible without affecting B and C for which we don't care about authenticating. Must refactor the whole thing due to a new requirement.

Other example: access to database directly. Any change in the database used could affect all over the code (if for example you do SQL statements all over without using a DAO).Your business logic would not have changed but the new requirement to switch DB would affect all of your code

You might be experiencing tight coupling if your objects are :

  • Hard to change. Symptoms : you need to add if statements into your classes each time you write a new variant of a dependency and want to communicate with it. Your code base has forests of if statements possibly operating on global variables, making it a nightmare to debug and maintain.

  • Fragile. Symptoms : a bug in an object can ripple through an unexpected number of other objects across the whole system. It is difficult to predict the consequences of changes you want to make in objects for lack of clear contracts between dependencies.

  • Hard to reuse. Symptom : reusing an object in a different context implies dragging along all its dependencies and their details, some of which may be irrelevant to that new context.

  • Hard to test. Symptoms : your automated tests need to glue together large clusters of objects before doing anything, which makes them slow as hell. Your tests are brittle - a change in the details of one object ripples through all its dependencies' test setups and they easily get red.

The Law of Demeter explains some simple guidelines for a loose coupling.

On the practical side, you may also take a look at Lattix, an Eclipse plugin that help you map and refactor your dependencies

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top