Design – What exactly is data coupling? What are its downsides

couplingdesign

I came across it in this article:

You call a method and pass it a parameter that doesn’t affect its control flow.

This is still coupling, but we’re starting to reach the kind that
isn’t so bad. Sometimes you need parameters! If you wanted to remove
all coupling you wouldn’t be able to pass data between objects at all.

class ScreenPrinter
  # This method is coupled to its parameter, because a change to that argument
  # can cause breakage (if we undefined to_s, for example).
  def print(text)
    output_to_screen(text.to_s)
  end
end

What if the text was just a string and print passed text into output_to_screen without accessing any of its properties or calling any of its methods, like so:

class ScreenPrinter
  def print(text)
    output_to_screen(text)
  end
end

Would it still be data coupling? It seems to me like the answer is yes – you can't predict what print will do without knowing what data is passed to it.

Is data coupling in such a case a bad thing?

Best Answer

The only substantial reference I could find to "data coupling" is quite a bit different from the Wikipedia and article definitions.

In the LDRA paper, data coupling is

The dependence of a software component on data not exclusively under the control of that software component.

Their example is:

For this demonstration of a Data Coupling defect consider two functions, CalculateAirspeed and Display-Airspeed both of which are called from the same Main Program (diagram above) and which share a global variable ‘speed’. Calculate-Airspeed computes a value for the variable ‘speed’, i.e. a set operation, whilst the function Display-Airspeed outputs the value of ‘speed’ to a display device, i.e. a use operation. The Main Program may be of the form illustrated below.

int main(){
 int speed, order;
loop:
 get(order);
 switch( order ){
 case 1: calculate_airspeed(speed);
 case 2: display_airspeed(speed);
 }
 goto loop;
}

The paper says display_airspeed is coupled to speed because it's declared and set independently of display_airspeed. display_airspeed will break if the order of operations is switched above.

I don't like this definition because I think spirit of the term data coupling is broader. Yes, display_airspeed is data coupled to speed, but that's irrelevant to the execution and flow of the program. Their example is more indicative of "Common coupling" according to the Wikipedia entry.

The Wikipedia entry and the article you've read take a broader definition of data coupling. Wikipedia uses:

Data coupling occurs when modules share data through, for example, parameters. Each datum is an elementary piece, and these are the only data shared (e.g., passing an integer to a function that computes a square root).

What if the text was just a string and print passed text into output_to_screen without accessing any of its properties or calling any of its methods, like so: ... Would it still be data coupling?

Yes. print is still data-coupled in two ways.

  1. The existence of the parameter text is in itself data coupling according to the definition, because removing the parameter and making print parameter-less or adding a parameter would be a breaking change. Therefore print is data coupled to being passed a single parameter.
  2. As @Aelexe says, print is coupled to the type of text. Even in a dynamically-typed language like your example, if output_to_screen expects a Foo to be passed in, and I call print and pass it a Bar, it will break print (because print is incorrectly calling output_to_screen). Therefore print is data-coupled to the Foo type transitively because of output_to_screen. I'm not actually sure this is data coupling. It may actually be "external coupling" to the type of text.

By removing the call to to_s, you've removed what I believe is "Stamp coupling (Data-structured coupling)" (from Wikipedia's definition)

Stamp coupling occurs when modules share a composite data structure and use only parts of it, possibly different parts

In this case print only really needs a string, but the parameter is a different type, and print accesses the to_s member of text to retrieve a string value. Therefore print is couple to the structure of text and changing or undefining to_s is a breaking change.

Related Topic