Good Coupling and Bad Coupling : Evil Function

First, I'll just give you the answer:

a thing should not directly couple to what is already indirectly couple to

High cohesion low coupling is a lie. It doesn't tell you how low is low. Do you really want zero coupling? That means your program has no interaction; and according to linear algebra, the system is boring, cannot have complicated behaviors.

OOP is also a lie. Procedural program can stand alone with only procedures. Functional programming can stand alone with only functions. But OOP is not stand-alone, OOP needs to use both procedures and functions to work.

Now I'm claiming that we don't really need functions in OOP.

What if I want to return two things? Function cannot!

output = function ( input1, input2, ... )

Let me explain with an example.

Suppose I need an Apple Juice maker.

    public interface IAppleJuicer
    {
        IFruitJuice smashing(IApple apples);
    }

This design of the AppleJuicer looks pretty standard and harmless right? It uses a function that inputs apple and outputs juice.

Functions couples inputs and outputs tightly, which makes it hard to expand the input / output, later.

What if then I upgrade it to mix two fruits, then upgrade to three?

public interface IAppleJuicer
{
        IFruitJuice smashing(IApple apples);
}

public interface IMixJuicer : IAppleJuicer //if it can mix two, of course it can mix one
{
        IFruitJuice smashing2(IApple apples, IBanana bananas);
}

public interface IAdvancedJuicer : IMixJuicer
{
        IFruitJuice smashing3(IApple apples, IBanana bananas, IWatermelon watermelon);
}
    }

The code looks very redundant. We can visualize that from the following coupling-diagram.

A couple to B := A's code somewhere contains B's type.
The red arrows are "coupling", the gray arrows are inheritance.

The red arrows are "coupling", the gray arrows are inheritance. (inheritance is a special kind of coupling, of course)

We see lots of coupling, especially redundant coupling.

As we mentioned first,

a thing should not directly couple to what is already indirectly couple to

For example, the MixedJuicer is directly coupled to the apple, but it's also indirectly coupled to the apple through the AppleJuicer.

We can minimize the coupling to 6, and I'll leave that as an exercise.

No alt text provided for this image


But, the point is not that we start with a bad design, then optimize it to a good one; there are things we can do so that we'll start with the good design in the first place: one such strategy is to not use Functions. Function is fundamentally evil because it violates S[O]LID, and SO[L]ID, and SOL[I]D, and SOLI[D]

Another thing bad about function :

Functions couples inputs and outputs in time, such that the program gets stuck waiting for the output.

Because the function "returns" something, the program awaits for that return and cannot move on. What if computing that return takes a lot of time??

If we don't use functions, and only use setters, we can solve all the problems above.

In conclusion, Good couplings scales as O(N), Bad couplings scales as O(N^2).

To view or add a comment, sign in

More articles by John Li

Explore content categories