Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ensure method A is called after every call of B (an abstract implemented method)?

Tags:

java

Having this tasteful class

     public abstract class CakeSkill 
     {

         //.. 

         boolean cherry=false;

         private void finalMandatoryTouch()
         {        
              cherry=true;
         }                
         abstract public void cook();
     }

A class that extends it would be something like

     class Cheff extends CakeSkill 
     {
         //..

         void cook()
         {
         //..Secret recipe
         }     
     }

But of course this won't work,

finalMandaroryTouch() hasn't been called, then no cake will end with a cherry..

[EDIT]

This one could be a solution

       class MemoriousCheff extends CakeSkill 
       {
           //..

           void cook()
           {
               //..Secret recipe
               finalMandatoryTouch();
           }     
       }

but requires :

  • Cheff to have a perfect memory that don't forget to call finalMandatoryTouch()
  • Making finalMandatoryTouch() to be protected (at least)

[/EDIT]

It would be great! (but no Java) if something like this could be done

  abstract public void cook()   
  {  
    @implementedMethod

    finalMandatoryTouch();        
  }

How can be implemented this useful functionality ?

Thank you very much

like image 892
Hernán Eche Avatar asked Dec 05 '22 21:12

Hernán Eche


2 Answers

Change cook to a protected method cookImpl then have a public final method called cook:

public final void cook()
{
    cookImpl();
    finalMandatoryTouch();
}

protected abstract void cookImpl();

That way the subclass only needs to worry about cookImpl, but callers of cook get the cherry on top. Callers not in the same package or class hierarchy won't even see cookImpl, so won't be able to call it directly.

This is the template method pattern, basically.

like image 166
Jon Skeet Avatar answered May 20 '23 08:05

Jon Skeet


It's called the Template method pattern.

final public void cook() {  
    mainCookRecipe();
    finalMandatoryTouch();        
}

abstract public void mainCookRecipe();
like image 28
Christian Semrau Avatar answered May 20 '23 06:05

Christian Semrau