开发者

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

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开发者_如何学C]

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


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.


It's called the Template method pattern.

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

abstract public void mainCookRecipe();


public abstract class CakeSkill {

    public void cook() {
        doCook();
        finalMandatoryTouch();
    }

    protected abstract doCook();

    private finalMandatoryTouch() { ... }
}

Etc.


You could change your cook() method to an actual method and then invoke a separate abstract method as well as your finalMandatoryTouch() method.

In your abstract class:

 public void cook() {
     specificCook();
     finalMandatoryTouch();
 }

 abstract void specificCook();


It seems that inheritance is not the right way to model your problem. In Java you can only inherit from one class, and since it's also a very static relationship, it limits your chef in the skills he can perform.

A better way would be to use composition. Cooking skills could be strategies that the chef performs:

interface CookingSkill {
  void cook();
}

class CakeSkill implements CookingSkill {
  private boolean cherry = false;
  private void finalMandatoryTouch() {
    cherry = true;
  }
  public void cook() {
    //...
    finalMandatoryTouch();
  }
}

class Chef {
  private CookingSkill cookingSkill;
  // getters and setters ...
  public void cook() {
    // ...
    cookingSkill.cook();
    // ...
  }
}

Now you can assign different cooking skills to your chef.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜