2

Two of the OOP metrics, Coupling Between Object classes (CBO) and Polymorphism Factor (PF) both measure coupling.

Is there an instance where of them has a higher coupling while another has a lower coupling? Is interface inheritance one such situation?

Also, how does each of them measure coupling?

Kilian Foth
  • 110,899
Char
  • 41

1 Answers1

3

The coupling between object classes (CBO) is a metric proposed by Chidamber & Kemerer to measure for a class to how much other classes it is coupled. A coupling means that an object of one class use methods or properties of an object in another class.

The polymorphic factor (PF) is a metric proposed by Abreu & Melo to measure how much a derived type overrides a method from the base class. It's calculated by counting the number of overridden methods compared to the number of methods.

These are independent measures, so in theory you can find any kind of relationship. But let's have a look at an an example to show how they relate in practice.

Suppose you have classes for representing different shapes (Circle, Square, etc...) and a class Figure, composed of several shapes. Figure has a draw() function that invokes a drawing method for each of its shapes.

  • Uggly implementation: each shape as an own independent class with own specific drawing function (e.g. draw_circle(), draw_square(), ...). Figure must then be coupled to all the shapes, with a lot of conditionals to cope with the different shapes. Every time you add a new shape, you add a new coupling.
    • CBO = N, where N is the number of shapes.
    • PF = 0 because there's no inheritance and hence no overriding.
  • Polymorphic implementation: each shape inherits from a superclass Shape and overrides the polymorphic draw() function. Figure only knows about Shape.
    • CBO = 1, because Figure only invokes the draw() on a Shape object .
    • PF tends to 100% (precisely it's N/(2+N) because Figure::draw() and Shape::draw() are no overrides, but Shape::draw() is overridden by N shapes

The common assumption is that a system with low coupling is easier to maintain. Therefore, many design patterns intend to reduce coupling. In most of the cases, polymorphism is the enabler for a decoupling.

Abstraction is the key, not the language feature used to implement it. Interface inheritance and normal inheritance are two ways to achieve abstraction. Interface inheritance requires you to provide an implementation for the interface functions (i.e. to provide an override for abstract functions which are not defined). It hence increases mathematically PF. However, some languages like C++ don't have interfaces but use pure virtual functions eventually with multiple inheritance to do the same, with identical PF. In our example, the inheritance is the enable for reducing coupling.

Christophe
  • 81,699