The Artima Developer Community
Sponsored Link

Weblogs Forum
Coupling is not neccessarily a bad thing!

35 replies on 3 pages. Most recent reply: May 5, 2005 11:49 PM by Greg Jorgensen

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 35 replies on 3 pages [ 1 2 3 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Coupling is not neccessarily a bad thing! (View in Weblogs)
Posted: Apr 30, 2005 11:35 AM
Reply to this message Reply
Summary
There is appears to be a school of thought that code coupling is to be avoided at all costs. This is a frustrating over-simplification.
Advertisement
A mantra I keep hearing over and over again is: inheritance is dangerous because it introduces unneccessary coupling. I disagree.

Coupling refers to dependencies between modular section of code, be they functions, classes, namespaces, header files, whatever.

Unneccessary coupling of code leads to code which is hard to maintain. Essentially what happens is a domino effect where changes to one section of code neccessitate changes in entirely unrelated sections of code. With some experience programmers quickly learn the harmful effects of over-coupling.

Judicious coupling (such as through inheritance) however is neccessary to a certain degree in order to maintain code cohesion, (i.e. logical grouping of related segments of code), and can be used to reduce unneccessary coupling elsewhere.

Within the context of OOP a class is the primary modular unit. A class which makes all of its fields public (without good reason) is an example of over-coupling. Any change to the class implementation will reverberate and affect any other class which plays with its member fields.

When one class inherits from another it increases coupling, obviously, but it does so in a very controlled manner. The thing that many programmers seem to be overlooking is that when using base classes, often what happens is that a new class is created solely to represent common functionality, so coupling between this base class and inherited classes is to be expected.

Consider the following example:

class Cat {
  void meow();
  void eat(); 
  void sleep(); 
};

class Dog {
  void bark();
  void eat(); 
  void sleep(); 
};

class Bird {
  void tweet(); 
  void eat(); 
  void sleep();
};
Clearly this would be more effectively written as:
class Pet {
  void eat(); 
  void sleep();
}

class Cat : Pet {
  void meow();
};

class Dog : Pet { 
  void bark();
};

class Bird : Pet {
  void tweet(); 
};
There is of course a coupling between Pet and the other classes but this coupling is correct and reduces the neccessity for coupling in other contexts by increasing the level of abstraction which can be used.

My point is simply that coupling is not automatically a bad thing.


Mark Finkle

Posts: 3
Nickname: mfinkle
Registered: Apr, 2005

Re: Coupling is not neccessarily a bad thing! Posted: Apr 30, 2005 3:44 PM
Reply to this message Reply
You are assuming that cats, dogs and birds "eat" and "sleep" the same way.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: Apr 30, 2005 5:25 PM
Reply to this message Reply
> You are assuming that cats, dogs and birds "eat" and
> "sleep" the same way.

Yes I am for the purpose of this example.

Matthew Wilson

Posts: 145
Nickname: bigboy
Registered: Jun, 2004

Re: Coupling is not neccessarily a bad thing! Posted: Apr 30, 2005 6:40 PM
Reply to this message Reply
I agree that coupling is not 100% bad in 100% of cases, but it is the dirtiest word in software engineering for good reason. Any and all coupling should be avoided wherever practicable. Visit any non-trivial library / framework, and you'll find the seeds of its inevitable decline sown in its ignorance of, or nonchalent acceptance of, coupling. For all that I am the world's worst documentor, which no doubt holds back them enormously, the STLSoft libraries (http://stlsoft.org/) continue to prosper because, IMO (and that of many users), avoidance of coupling is given almost equal top-billing with correctness, robustness and portability. You don't have to look far to see other libraries (C++ and otherwise) that die in the arse shortly after inception because they fail to follow this path.

As for your animals, I think you're mistaking, or mistakenly representing, apparent taxonomical commonality (i.e. they're animals) with substitutability, which is righly appreciated [see C++ Gems] as the singular criterion for inheritance based relationships.

indranil banerjee

Posts: 38
Nickname: indranil
Registered: Nov, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 1, 2005 6:18 AM
Reply to this message Reply
If two objects/components/things need to communicate there has to be some kind of coupling between them. So it is imposssible and somewhat meaningless to remove coupling all together. Our goal in designing systems is all about managing dependencies between components and not introducing unnecessary coupling.

Here are a couple of good articles from Herb Sutter on the subject with the title Uses and Abuses of Inheritance

http://www.gotw.ca/publications/mill06.htm
http://www.gotw.ca/publications/mill07.htm

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 1, 2005 10:03 AM
Reply to this message Reply
So for all and intents and purposes then we are all on the same page. Some coupling is warranted under specific circumstances, while in general minimizing coupling is an important activity.

Then only point of contention is perhaps a difference on opinions in certain cases as to where to draw the line in the sand as to what specific conciditions warrant some coupling.

Mark Finkle

Posts: 3
Nickname: mfinkle
Registered: Apr, 2005

Re: Coupling is not neccessarily a bad thing! Posted: May 1, 2005 11:19 PM
Reply to this message Reply
I guess my point is that your example is very trivial and does not explore the compromise that needs to occur. When you use inheritance you are making a decision that "coupling" is more important than "reuse".

When building large object hierarchies it is often very difficult to extract pieces out for reusing in other soutions. Its usually an all or nothing kind of thing. UI frameworks are notorious for that kind of problem. They typically use inheritance deeply.

In the end, I agree that coupling via inheritance is a common way to solve problems. But people need to weigh the consequences. Applied in a "hammer/nail" manner, it will likely cause lots of maintenance problems down the road.

Greg Jorgensen

Posts: 65
Nickname: gregjor
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 1, 2005 11:23 PM
Reply to this message Reply
It's not that coupling is always bad; without coupling modules can't communicate. The goal is to couple modules cleanly and only as tightly as necessary, not to eliminate all coupling.

I think Glenford Myers first defined and described coupling (and module strength) in his books "Composite/Structured Design" and "Reliable Software Through Composite Design." Steve McConnell updated the concepts in his "Code Complete" books. Wikipedia has some definitions:

http://c2.com/cgi/wiki?CouplingAndCohesion

I don't think subclasses have a "bad" coupling relationship with their base class. Unrelated classes are equivalent to separate modules, but child classes don't exist without the parent class and its context. A derived class is an extension of the base class, not a separate class. The subclass is tightly coupled to its parent because of the "is a" relationship.

In your example, there's nothing wrong with the coupling between dog and pet, or cat and pet. As long as dog and cat aren't directly coupled to each other.

I'm not sure that relationships among class definitions are really the same thing as coupling: classes are abstractions, type definitions. Coupling more correctly refers to instances of classes, not classes themselves.

Greg Jorgensen
PDXperts LLC
Portland, Oregon USA

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 1, 2005 11:25 PM
Reply to this message Reply
> I guess my point is that your example is very trivial and
> does not explore the compromise that needs to occur. When
> you use inheritance you are making a decision that
> "coupling" is more important than "reuse".

Yes, in retrospect my example stinks. I half-regret opening this particular can of worms.

> When building large object hierarchies it is often very
> difficult to extract pieces out for reusing in other
> soutions. Its usually an all or nothing kind of thing. UI
> frameworks are notorious for that kind of problem. They
> typically use inheritance deeply.
>
> In the end, I agree that coupling via inheritance is a
> common way to solve problems. But people need to weigh the
> consequences. Applied in a "hammer/nail" manner, it will
> likely cause lots of maintenance problems down the road.

I agree with this sentiment.

Javid Jamae

Posts: 16
Nickname: javidjamae
Registered: Jan, 2003

Re: Coupling is not neccessarily a bad thing! Posted: May 2, 2005 10:50 AM
Reply to this message Reply
> When building large object hierarchies it is often very
> difficult to extract pieces out for reusing in other
> soutions. Its usually an all or nothing kind of thing. UI
> frameworks are notorious for that kind of problem. They
> typically use inheritance deeply.
>
> In the end, I agree that coupling via inheritance is a
> common way to solve problems. But people need to weigh the
> consequences. Applied in a "hammer/nail" manner, it will
> likely cause lots of maintenance problems down the road.


I agree with this.

I think that inheritence should be used only if it aids in reuse AND if the classes are to be used polymorphically. Inheritence should only be used for reuse if the code that refers to the parent can use any child, without depending on the details of the child. This is known as the Liskov Substitution Principle.

If you just want to eliminate duplicate code (without the need for polymorphism), use composition.

Think of a system that sends and collects messages. If you have SentMessage and ReceivedMessage classes, but no code ever uses objects of those two classes polymorphically, does it make sense to make them both extend a Message class, or implement a Message interface. They're *kinda* the same, but not really. If client code always has to determine if its operating on a SentMessage or a ReceivedMessage, then what is the point of inheritence? Why couple them in this way?

In my opinion, a better and often overlooked way of "coupling" code is through composition (a.k.a. the Strategy pattern). You can *always* substitute an inheritence relationship between two classes with a composition relationship.

Rant: If I had my way, OO languages would only support inheriting abstract classes, and an abstract class could only have abstract or final methods. All non-abstract classes would essentially be final. Whenever I've worked on a development team that self-imposes this restriction, I see much better designs emerge through use of composition.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 2, 2005 11:06 AM
Reply to this message Reply
> I think that inheritence should be used only if it aids in
> reuse AND if the classes are to be used polymorphically.
> Inheritence should only be used for reuse if the code
> that refers to the parent can use any child, without
> depending on the details of the child. This is known as
> the Liskov Substitution Principle.
>
> If you just want to eliminate duplicate code (without the
> need for polymorphism), use composition.

My problem is that using composition in a language like C++ requires forwarding functions, which increases the amount of code that needs to be maintained.

If I had my way, languages like Java and C++ would support delegations which would automatically create forwarding functions for a given interface. This is what I did with Heron (though I still haven't implemented it, it is in the specification).

Then composition wouldn't be such a pain in the buttocks.

The other problem with many languages is this horrible confusion between inheritance and subtyping. They are not the same thing, though they are used interchangeably because in languages like C++, the only way to subtype is to inherit. This I think is the root cause of many problems.

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Coupling is not neccessarily a bad thing! Posted: May 2, 2005 11:55 AM
Reply to this message Reply
> Yes, in retrospect my example stinks. I half-regret opening this particular can of worms.

Ah ha I guess you've already realized it is a purr-fect example of the shortcomings of coupling.

As we continue to build our animal management program over the ensuing years, our user base begin to request support of ferral cats, dingos, golden mantled ground squirrels and more. But those aren't pets. They do eat and sleep, but they don't have other attributes of "pets." How can we get that eating and sleeping behavior (and others we've added as the system grew some) into them, without all the attributes that pets have? Maybe we had the wrong strategy?

Greg Jorgensen

Posts: 65
Nickname: gregjor
Registered: Feb, 2004

Re: Coupling is not neccessarily a bad thing! Posted: May 2, 2005 12:33 PM
Reply to this message Reply
> Ah ha I guess you've already realized it is a purr-fect
> example of the shortcomings of coupling.
>
> As we continue to build our animal management program over
> the ensuing years, our user base begin to request support
> of ferral cats, dingos, golden mantled ground squirrels
> and more. But those aren't pets. They do eat and
> sleep, but they don't have other attributes of "pets."

If the original intention was to model pets, then adding wild animals will of course break the abstractions. That is not a problem caused by coupling; it's a problem of missed or changing requirements.

The class structure suitable for describing some behaviors of household pets is not necessarily suitable for modeling a zoo, or all animals. Bad class design is just that; it's not an evil created by inheritance, and it has little to do with coupling.

Neeraj Sangal

Posts: 4
Nickname: nsangal
Registered: May, 2005

Re: Coupling is not neccessarily a bad thing! Posted: May 2, 2005 9:28 PM
Reply to this message Reply
This discussion is moving in the direction of the benefits and drawbacks of inheritance. Inheritance is just one form of coupling. When a class calls a method in another class or refers to its data members that is coupling as well.

On another level, there are different types of couplings.

- "Design Time" coupling: If the developer of module A needs to know module B then A is coupled to B. Patterns such as a 'listener' or a 'visitor' or a 'facade' are designed to reduce or change this form of coupling. Prudent management of these couplings leads to design modularity.

- "Operating Time" coupling (from Parnas). If the correct operation of module A requires the correct operation of module B then A is coupled to B. Notice that introducing the listener pattern or an interface would not necessarily change coupling between modules. Understanding these couplings is necessary in understanding how a program works.

There is considerable confusion because these forms of coupling are closely related especially because often one form of coupling implies the other. Coupling is fundamental to architecture: Proper coupling leads to modularity; improper coupling leads to monolithic systems.

Neeraj Sangal
Lattix, Inc.

Vincent O'Sullivan

Posts: 724
Nickname: vincent
Registered: Nov, 2002

Re: Coupling is not neccessarily a bad thing! Posted: May 3, 2005 3:24 AM
Reply to this message Reply
> If the original intention was to model pets, then adding
> wild animals will of course break the abstractions. That
> is not a problem caused by coupling; it's a problem of
> missed or changing requirements.

That's like the train companies blaming the passengers for messing up their timetables.

The problem (in this case) is exactly one caused by coupling. New requirements are not problems just a fact of life. The problem is the inability to meet the new requirement using the work that has been put into the existing solution.

In any "real-world" software development project there will always be requirements that are missed or change (or are vague or even contradictory). Whilst a solution may initially look good, given the known requirements; the short-comings of that solution soon become apparent when a requirement arrives that requires an unpredicted extension to the code.

The apparently trivial pet example given is an apt example. It initially looked like a sound solution to a simple problem but fell apart the moment the design came under any pressure from an unforseen extension.

Flat View: This topic has 35 replies on 3 pages [ 1  2  3 | » ]
Topic: Working Around Non-Virtual Destructors Previous Topic   Next Topic Topic: Contract Enforcement for humanity ... ?


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us