I'm using an abstract base class to add logging functionality to all of my classes. It looks like this:
class AbstractLog
{
public:
virtual ~AbstractLog() = 0;
protected:
void LogException(const std::string &);
private:
SingletonLog *m_log; // defined elsewhere - is a singleton object
};
The LogException()
method writes the text to the log file defined in the SingletonLog
object, and then throws an exception.
I then use this as my base class for all subsequent classes (there can be hundreds/thousands of these over hundreds of libraries/DLLs).
This allows me to call LogException()
wherever I would normally throw an exception.
My question is whether or not this is good design/practice.
P.S.: I'm using inheritance simply to add functionality to all of my classes, not to implement any sort of polymorphism. On top of this, the concept of all of my classes having an is-a relationship with the AbstractLog
class is arguable (each class is-a loggable object? Well, yes I suppose they are, but only because I've made them so).
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.
Inheritance should only be used when: Both classes are in the same logical domain. The subclass is a proper subtype of the superclass. The superclass's implementation is necessary or appropriate for the subclass.
Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors (realizing an interface), to reuse code and to independently extend original software via public classes and interfaces.
Either your additions will be overwritten, or you'll have to manually migrate them into the update, which is time-consuming and risky. Alternatively, there may be times when it's not even possible to modify the base class. Consider the code in the standard library.
What you suggesting will work, I think better is to create log class ( inheriting from this interface ) and use it as in a way composition ( using interface ) than inheritance - composition is weaker connection between your logic class and log class. The best practice is the less class does the better. Additional benefit is that you will be able to extend log functionality any time you want without modification of business logic.
About this singleton, maybe proxy pattern is better ?
Hope, I helped :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With