Answer To Order Of Inheritance Problem

 

Yesterday, I asked the question as to which way two child classes should derive from one another. 

The problem situation was as follows: A business logic workflow class to register a new customer in the system, aptly named RegisterCustomerUseCase, was to be extended with additional behaviour. Firstly, we should be able to turn on and off the new workflow via a feature flag switch. Secondly, we want to be able to log activity in the RegisterCustomerUseCase for diagnostic purposes.

I dislike log statements littering functional code. They are a distraction from what is going on. Log statements exist to help developers debug their code. They do little for the application end-user. The Single Responsibility Principle encourages us to do logging removed from the functional code. One way of achieving this is to put logging into a derived class. In our example, we’ll do our diagnostic logging in LoggedRegisterCustomerUseCase. An entirely new class just for logging may seem a little bit contrived. Fair enough. I find value in it. As I said, I don’t like to have my code polluted with logging calls. Maybe try it out and see whether you like it?

Similarly, we ought to separate the feature flag conditional code. Why? A feature flag is temporary and exists only for a short while. We will want to remove it when the feature has been rolled out. If we place the feature flag conditional into our main workflow code, then we must modify code to remove it. However, if the feature flag switch resides in a separate class, we may delete that class without affecting the base class behaviour. 

I don’t use inheritance all that much as it imposes a rigid relationship on classes—but it works well here.

So much for a recap of the original scenario.

The question I posed yesterday was: 

Should FeatureFlaggedRegisterCustomerUseCase derive from LoggedRegisterCustomerUseCase or should it be the other way around?

 

Thank you to everyone who sent in your answers. The winner of the challenge is Andy Baird, who sent in the first correct answer. Well done, Andy!

 

Since the feature flag is temporary and will ultimately be removed, we would prefer FeatureFlaggedRegisterCustomerUseCase to be the child class of LoggedRegisterCustomerUseCase

If instead, we had the inheritance reversed, when we remove FeatureFlaggedRegisterCustomerUseCase, we would simultaneously break the inheritance hierarchy—LoggedRegisterCustomerUseCase is the child of a parent that no longer exists. We’d be forced to derive LoggedRegisterCustomerUseCase from RegisterCustomerUseCase, an unnecessary and undesirable modification.

And the promised twist? What if we wanted to log the feature flag calls? No problem. We can log inside the feature flag class—the Single Responsibility Principle (SRP) does not have a problem with such behaviour. 

Hold on. Why should we not log inside our main behavioural class, RegisterCustomerUseCase, but we can do so in FeatureFlaggedRegisterCustomerUseCase? The answer is simply this: It’s us programmers who are interested in the feature flagging as much as the logging. Both responsibilities belong to the same ‘Actor’, i.e. programmers, so the SRP is not violated. Putting logging or feature flagging into the base use case class is problematic since code serving two different ‘Actors’ would reside together.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply