When to use inheritance?

My friend and I had a little debate. I had to implement a browser observer class that raises an event whenever a browser is browsed (say, Internet explorer).

We created the Process Observer class, and here the discussion begins:

He said that the constructor should only accept strings (for example, iexplore.exe), and I said that we should inherit the "Process Watcher" to create a "browser watcher" that accepts the currently used browser enumeration, which the constructor will "translate" it on "iexplore". he said that we should use a utility function that will act as a translator.

I know that both paths are real and good, but I wonder what are the pros and cons of each, and what is suitable in our case.

+4
source share
6 answers

Recently, I’ve taken the “Keep it simple now and reorganize later if you need to extend it” approach.

What you are doing now seems pretty simple. You really only have one case that you are trying to deal with. Therefore, I would say that this time a simpler approach. In the end, if you never have to do another kind of observer, you avoid the extra complexity. However, copy it so as to facilitate the reorganization later if you need to.

In the future, if you find that you need a different type of observer, take the effort to reorganize it into an inheritance (or composition or any other template that you want to use). If your source code is done correctly, refactoring should be fairly simple, so you don't add a lot of extra work.

I found that this approach works pretty well for me. In cases where I really don't need inheritance, the code remains simple. But when I really need it, I can add it without any real problems.

+10
source

All things being equal, I prefer a simpler solution (one specific class that takes a string as a constructor parameter) for a more complex one (using the base class and subclass).

Inheritance is suitable if you want to change behavior : if the browser observer does what the normal process observer does not. But if you want to change the value of the data , just change the data.

+6
source

Unless you have a different use for ProcessWatcher than for the parent role of BrowserWatcher, you should not create one. If you use other observers that have common functionality that can be hosted by ProcessWatcher, then you should (both are isa relationships, so Rob criterion is met).

It's really that simple. Claiming that someday you will have other observers, this is not an argument in favor of creating a separate class. This is a mental tick that you should lose as soon as possible.

+3
source

Depending on which use case you have or which god you are following.

I'm not saying that “inheritance is evil,” but in general I follow the principle of “Enjoy composition over inheritance” to avoid excessive class hierarchies.

+1
source

Inheritance should only be used to implement the isa relationship.

As you can say that a “browser observer” is a specific instance of a “process observer,” then inheritance is appropriate for this architecture.

Therefore, for me, having the identity of what you are looking at goes through part of the development of the browser, the implementation of the "process observer" is definitely the way out.

Edit: More specifically, inheritance is when you want to specialize behavior. For example, most animals make a sound, but you can hope to provide what kind of sound to make in a class called "animal", you should wait for specialization.

So, we have the Horse class that provides neighing for its sound, the Dog class that provides bark for its sound, etc.

NTN

amuses

Rob

+1
source

I agree that in most cases, simplicity versus complexity is a good strategy if your simplicity is not too short-sighted (Herms link, write the code in such a way that you can easily regroup later).

However, I also know how difficult it is to plug this error in the ear, which encourages a more thorough design. If you still want to approve inheritance without thinking in terms of “base class” and “subclass”, you can simply define the interface (for example, IProcessWatcher) that ProcessWatcher implements. When you use a ProcessWatcher object, refer to it from an interface point of view, so that if you later decide to create a BrowserWatcher (or any other kind of ProcessWatcher), you can do this without forcing it to go down from the ProcessWatcher if it implements the IProcessWatcher interface.

Warning: Be careful. It's tempting to want to define an interface for each individual object, and let it run into it, it's just ridiculous. =)

Ultimately, you need to find something you are comfortable with, since you will have to maintain this code, and I think this can be a pleasant compromise, and not just “Inheritance or lack of inheritance”.

Good luck

0
source

All Articles