Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protected "stub" methods used only for overriding purposes considered good practice or not?

Sometimes when I extend one of my own classes, I want to (for the purpose of the subclass) "inject" one or two lines of code in the middle a method in the super class.

In these cases I sometimes add a call to an empty protected method for the subclass to override.

public void superClassMethod() {

    // some fairly long snippet of code

    doSubclassSpecificStuff();

    // some other fairly long snippet of code

}

// dummy method used for overriding purposes only!
protected void doSubclassSpecificStuff() {
}

When doing this several times in the same class I must say it looks quit awkward / ugly so my questions:

  1. Is this way of "opening up" for subclasses to "inject" code in the middle of methods considered good practice or not?
  2. Is the pattern (anti-pattern?) called something?
  3. Has it been used in any well known API / library? (Note that I'm talking about non-abstract classes.)
  4. Are there any better alternatives?

The only alternative I can come up with is to use something like the command pattern and have a setMiddleOfMethodHandler(SomeRunnableHandler), and call handler.doSubclassSpecificStuff() instead of the dummy-method. It has a few drawbacks as I see it though, such as for instance not being able to touch protected data.

like image 665
aioobe Avatar asked Dec 16 '10 20:12

aioobe


People also ask

Can you override a protected method?

Yes, the protected method of a superclass can be overridden by a subclass. If the superclass method is protected, the subclass overridden method can have protected or public (but not default or private) which means the subclass overridden method can not have a weaker access specifier.

What are protected methods in Java?

Basically, the protected keyword is an access modifier for method and variable of a class. When a method or a variable is marked as protected, it can be accessed from: Within the enclosing class. Other classes in the same package as the enclosing class.

Can we write test cases for protected methods?

In most cases, you do not want to write tests for non-public methods, because that would make the tests dependent on the internal implementation of a class. But there are always exceptions.

What is protected method in C#?

protected: The type or member can be accessed only by code in the same class , or in a class that is derived from that class . internal: The type or member can be accessed by any code in the same assembly, but not from another assembly.


3 Answers

You've just discovered the Template method design pattern. Note though that normally the methods that comprise the individual steps are abstract (rather than empty and protected) so that subclasses must override them.

like image 136
John Topley Avatar answered Oct 25 '22 00:10

John Topley


There is the Template method pattern. The idea there is that much of the work is common, except for a few bits, which are handled by a subclass implemented method.

like image 25
sblundy Avatar answered Oct 25 '22 00:10

sblundy


Yes, this is a legitimate way to do things; I've used it myself.

The only problem I can see is not the specific technique, but the fact that you are using subclasses of concrete (read: non-abstract) classes at all. Subclassing concrete classes has many subtle problems, so I would recommend to avoid it altogether. See e.g. http://en.wikipedia.org/wiki/Liskov_substitution_principle for an explanation of what you must do to properly subclass a class, and the problems involved. Also, in "Effective Java" Block recommends using composition (Item 16).

Another approach (that avoids subclassing) would be to use Dependency Injection. Your method would accept a parameter of a type that implements the interface ISpecificStuff, which specifies a method doSubclassSpecificStuff():

public void superClassMethod(ISpecificStuff specificStuff) {
  ....
  specificStuff.doSubclassSpecificStuff();
  ....
}

That way, any caller can decide what the method should do. This avoids the need for subclassing. Of course, you could inject via a constructor, if you need it in more than one method.

like image 2
sleske Avatar answered Oct 24 '22 23:10

sleske