Domanda

EDIT 1: By generic I don't mean a generic method for java's generic classes, but a method that I have written to be essential in the use of my program.

I'm trying to write a program (sort of a process integrator) that allows 3rd party developers to add their own functional pieces to a task net. These pieces are objects created from classes which have a runProcess()-method (the class implements specialRunnable).

I wan't to force a log entry to be written whenever the object's runProcess()- method is called. However, I don't want the implementation (writing to log) to be neither in the 3rd party class nor in the class which makes the method call.

I've searched and tried to do it trough inheritance and implementing an interface, but haven't found a solution. Here's and example of how I would like it to work:

 public abstract class Process{

 public void runProcess(){   
 // when runProcess() is called all specialized processes write to log first
 writeToLog();
 // then do their thing which is defined in their class
 doYourProcessSpecificThing();

 }

 public void writeToLog(){ 
 //writing to log comes here
 }

 // specialized processes have to define what is done
 public abstract void doYourProcessSpecificThing(); 

Specialized class:

public class Special3rdPartyProcess  extends Process implements specialRunnable{

runProcess(){
super.runProcess();
}

doYourProcessSpecificThing(){
// this is where the magic happens
}

To sum what I want: I want all processes to be started with runProcess() command, and I want a log entry whenever it is done, but I DON'T want the 3rd party developers to decide how or if the entry is written. Also I don't want it done like this:

writeToLog();
task1.runProcess();

writeToLog();
task2.runProcess

Thanks!

È stato utile?

Soluzione

If you make your runProcess method final, then subclasses won't be able to override your method, and this can ensure that writeToLog is called.

You can make writeToLog private to not expose the implementation.

You can make doYourProcessSpecificThing protected so that it can't be called directly, but subclasses can still define their own implementation.

This is called the Template Method Pattern. This allows the implementer (you) to define what specific behavior can be overridden, yet retaining control over the overall process/algorithm.

Altri suggerimenti

You can simply make runProcess final in the base class, so subclasses can't override it:

public abstract class Process{

 public final void runProcess(){   
   writeToLog();
   doYourProcessSpecificThing();
 }

 //private: implementation detail
 private void writeToLog(){ 
 }

 //protected: calling classes don't need to know about this method
 protected abstract void doYourProcessSpecificThing(); 

And your subclass:

public class Special3rdPartyProcess  extends Process implements specialRunnable{
  protected final void doYourProcessSpecificThing(){
    // this is where the magic happens
  }
}

Then the client code simply does:

Special3rdPartyProcess spp = ...;
spp.runProcess();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top