When you define a class, is inheriting a logger such as log4cxx a good design?
Assume I am defining a class called MyClass.
When I want a logger, I use a pointer to an abstract logger class as a member variable of MyClass. Then during the construction of MyClass, I can pass in a pointer to a concrete logger class in the initializer list of MyClass.
Then in places where I want to write to the logger, I can check if the pointer to the logger is null before writing to the logger.
Question: Irrespective of what I do, is making MyClass inherit a logger class a good design?
-
3Composition over inheritance might apply here. I.e. "MyClass has a logger" is probably better than "MyClass is a logger".JonasH– JonasH03/27/2024 12:37:56Commented Mar 27, 2024 at 12:37
-
I don't understand why the severe downvoting, question has everything required. I also recommend composition over inheritance.jimjim– jimjim03/27/2024 14:00:16Commented Mar 27, 2024 at 14:00
-
2Agreed with @jimjim. A -4 score on this question is ridiculous. I think this is on topic for this community. I up-voted the question, myself.Greg Burghardt– Greg Burghardt03/27/2024 15:21:27Commented Mar 27, 2024 at 15:21
-
I am confused by the question. In the title, and in your concluding sentence, you ask if inheriting a logger is a good idea. But in the body of the question, you talk about storing the logger as a member variable, not inheriting it. Which of these designs are you asking about? (I am wondering if you misunderstand the word "inherit").John Wu– John Wu03/28/2024 05:43:07Commented Mar 28, 2024 at 5:43
-
John Wu, I had only one question. That is what I asked at the end. But Stack Exchange does not allow me to ask just the question.Dhammika Wijesundera– Dhammika Wijesundera03/30/2024 17:44:20Commented Mar 30, 2024 at 17:44
1 Answer 1
Assuming the primary responsibility of MyClass is not logging, then inheritance is not the right tool. Composition is much easier to manage here, but you also want to check for a null logger when logging messages. The real problem is a null pointer to a logger.
This is precisely the problem that the Null Object Pattern solves.
Instead of checking for null, provide a default implementation of the abstract class or interface for the logger which does nothing when calling the methods. This provides a safe implementation without requiring MyClass to constantly check for null.
In the setter for the logger, check for an incoming null value, and replace it with the "null object" instead.
-
1Null object pattern remains my favorite pattern. It’s a great way to teach that just because a command says to do something doesn’t mean anything should be done.candied_orange– candied_orange03/28/2024 02:33:44Commented Mar 28, 2024 at 2:33
-
@candied_orange, I find it to be one of the more subtle and elegant design patterns that reduces the friction in your code. Logic just seems to flow more easily when you don't need to worry about null. It's one of my favorites, as well.Greg Burghardt– Greg Burghardt03/28/2024 14:22:08Commented Mar 28, 2024 at 14:22
-
Thanks very much for all the comments and the answers.Dhammika Wijesundera– Dhammika Wijesundera03/29/2024 12:52:51Commented Mar 29, 2024 at 12:52