Protected "stub" methods used only for revaluation are considered good practice or not?

Sometimes, when I extend one of my own classes, I want (for the purposes of the subclass) to “enter” one or two lines of code in the middle of the method in the superclass.

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

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 you do this several times in the same class, I have to say that it looks awkward / ugly, so my questions are:

  • Is this “discovery” method for subclasses to “enter” code in the middle of methods considered good practice or not?
  • Is the template (anti-template?) Something named?
  • Is it used in any known API / library? (Note that I'm talking about non-abstract classes.)
  • Are there any better alternatives?

The only alternative I can come up with is to use something like a command template and have setMiddleOfMethodHandler(SomeRunnableHandler) and call handler.doSubclassSpecificStuff() instead of a dummy method. This has several drawbacks, as I see it, although, for example, for example, I can not touch protected data.

+7
source share
6 answers

You have just discovered the template method . Note that usually the methods that make up the individual steps are abstract (rather than empty and protected), so subclasses should override them.

+9
source

There is a template template template . The idea is that most of the work is general, with the exception of a few bits that are processed by the subclass method.

+4
source

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

The only problem I see is not a specific technique, but the fact that you use subclasses of specific (read: not abstract) classes in general. Subclassing specific classes has many subtle issues, so I would recommend avoiding this at all. See http://en.wikipedia.org/wiki/Liskov_substitution_principle for an explanation of what you should do to properly subclass a class and its associated problems. In addition, it is recommended that you use composition in the Effective Java block (paragraph 16).

Another approach (which avoids subclassification) is to use Injection Dependency . Your method will take a type parameter that implements the ISpecificStuff interface, which defines the doSubclassSpecificStuff() method:

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

That way, any caller can decide what the method should do. This avoids the need for subclassification. Of course, you can enter through the constructor if you need it with more than one method.

+2
source

It seems suspicious to me. I think the reason you have to do this is a design flaw. Your method, which should be "split", is probably too much. The solution is to split it in stages and give the concrete value "doSubclassSpecificStuff".

For example:

 void Live() { BeBorn(); DoCrazyStuff(); // this can be made protected virtual Die(); } 
+1
source

Yes, that’s fine. This is an example of a template method template in which you use inheritance to define a method that supports the well-known "skeleton" but can have custom logic.

 public abstract class Ancestor { protected virtual void CanOverrideThisStep(){...} protected abstract void MustDefineThisStep(); protected sealed void MustDoExactlyThis(){...} private void HideThisStepFromEveryone(){...} public sealed void TemplateMethod() { ... CanOverrideThisStep(); ... MustDoExactlyThis(); ... MustDefineThisStep(); ... HideThisStepFromEveryone(); } } 

Inheriting ancestors above must define a body for MustDefineThisStep () and can optionally override CanOverrideThisStep (), but cannot touch MustDoExactlyThis (), HideThisStepFromEveryone, or the TemplateMethod driving function itself. However, except HideThisStepFromEveryone, all subtopics are available for child classes, so the child can use MustDoExactlyThis () in the implementation of MustDefineThisStep ().

This is very common; such constructs are the reason that OO languages ​​have access modifiers that are at their disposal. The template is very useful for workflows, file processing, and other tasks that are usually the same, but have slightly different implementation details.

+1
source

I usually use this method as a way to handle special cases. I will write things like this:

 public void foo() { theData=getTheData(); preprocessDataHook(theData); putTheData(theData); } protected void preprocessDataHook(SomeObject theData) { // Nop. Available for subclasses to override. } 

A subclass that does not need data preprocessing may simply not override this function. A subclass that requires preprocessing can override a function.

If we expected that all or most subclasses would need pre-processing, then this should be an abstract function to force the programmer to implement it or make a conscious decision to do nothing. But if this is just a random subclass that needs to do something here, I think this is the right approach.

+1
source

All Articles