Entering functionexecute Initializing some variables Starting algorithm One step forward One step forward ... Ending algorithm Cleaning some mess Exiting functionexecute Entering function Initializing some variables Starting algorithm One step forward One step forward ... Ending algorithm Cleaning some mess Exiting function Entering execute Initializing some variables Starting algorithm One step forward One step forward ... Ending algorithm Cleaning some mess Exiting execute I have the feeling that you absolutlyabsolutly want to use a pattern. Be warnedRemember that using a bad usage of design pattern doesn't alwayspatterns may result in a better code ! Remember that design patterns must serve the developper and not the oppositeless maintainable/readable.
That beeing said...
Your case is tricky as it seems you want to do 2 kinds of logging:
For the first case, at the moment you want to log some things inside a function, you have to do it... inside the function. You could use the template method pattern to make things a bit prettier but I think it's overkilloverkill in this case.
I have the feeling that you absolutly want to use a pattern. Be warned that using a design pattern doesn't always result in a better code ! Remember that design patterns must serve the developper and not the opposite.
Your case is tricky as it seems you want to do 2 kinds of logging:
For the first case, at the moment you want to log some things inside a function, you have to do it... inside the function. You could use the template method pattern to make things a bit prettier but I think it's overkill in this case.
I have the feeling that you absolutly want to use a pattern. Remember that a bad usage of design patterns may result in a code less maintainable/readable.
That beeing said...
Your case is tricky as it seems you want to do 2 kinds of logging:
For the first case, at the moment you want to log some things inside a function, you have to do it... inside the function. You could use the template method pattern to make things a bit prettier but I think it's overkill in this case.
AsI have the feeling that you said,absolutly want to use a pattern. Be warned that using the decoratora design pattern isdoesn't always result in a good solutionbetter code ! Remember that design patterns must serve the developper and not the opposite.
Here's a canvasYour case is tricky as it seems you want to do 2 kinds of howlogging:
- Logging some steps of your logical functionality (inside
execute) - Logging around function calls (entering/exiting a function) (outside
execute)
For the first case, at the moment you want to log some things inside a function, you have to do it... inside the function. You could be implemented:use the template method pattern to make things a bit prettier but I think it's overkill in this case.
public final class MyFunctionMyBusinessFunction extends AFunctionBaseFunction { @Override public final void execute() { //dolog.info("Initializing thesome realvariables"); computation here int i = 0; double d = 1.0; log.info("Starting algorithm"); for(...) { ... log.info("One step forward"); ... } log.info("Ending algorithm"); ... log.info("Cleaning some mess"); ... } } For the second case, the decorator pattern is the way to go:
public final class MyLoggedFunctionLoggingFunction extends AFunctionBaseFunction { private final AFunctionBaseFunction origin; public MyLoggedFunctionLoggingFunction(AFunctionBaseFunction origin) { this.origin = origin; } @Override public final void execute() { //log before.info("Entering functionexecute"); origin.execute(); //real call to the function //log after.info("Exiting functionexecute"); } } Usage ifAnd you only want to perform the executecould use it like this in BusinessClass:
AFunctionpublic final BusinessClass { private final BaseFunction f1; public BusinessClass() { this.f1 = new MyFunctionLoggingFunction(new MyBusinessFunction()); } public final void doFunction() { f1.execute(); } } Usage if you also want the start/end of the functionA call to be loggeddoFunction will log this:
AFunctionEntering f1function Initializing =some newvariables Starting MyLoggedFunction(newalgorithm One MyFunction());step forward f1One step forward .execute();.. Ending algorithm Cleaning some mess Exiting function As you said, using the decorator pattern is a good solution.
Here's a canvas of how it could be implemented:
public final class MyFunction extends AFunction { @Override public final void execute() { //do the real computation here } } public final class MyLoggedFunction extends AFunction { private final AFunction origin; public MyLoggedFunction(AFunction origin) { this.origin = origin; } @Override public final void execute() { //log before function origin.execute(); //real call to the function //log after function } } Usage if you only want to perform the execute:
AFunction f1 = new MyFunction(); f1.execute(); Usage if you also want the start/end of the function to be logged:
AFunction f1 = new MyLoggedFunction(new MyFunction()); f1.execute(); I have the feeling that you absolutly want to use a pattern. Be warned that using a design pattern doesn't always result in a better code ! Remember that design patterns must serve the developper and not the opposite.
Your case is tricky as it seems you want to do 2 kinds of logging:
- Logging some steps of your logical functionality (inside
execute) - Logging around function calls (entering/exiting a function) (outside
execute)
For the first case, at the moment you want to log some things inside a function, you have to do it... inside the function. You could use the template method pattern to make things a bit prettier but I think it's overkill in this case.
public final class MyBusinessFunction extends BaseFunction { @Override public final void execute() { log.info("Initializing some variables"); int i = 0; double d = 1.0; log.info("Starting algorithm"); for(...) { ... log.info("One step forward"); ... } log.info("Ending algorithm"); ... log.info("Cleaning some mess"); ... } } For the second case, the decorator pattern is the way to go:
public final class LoggingFunction extends BaseFunction { private final BaseFunction origin; public LoggingFunction(BaseFunction origin) { this.origin = origin; } @Override public final void execute() { log.info("Entering execute"); origin.execute(); log.info("Exiting execute"); } } And you could use it like this in BusinessClass:
public final BusinessClass { private final BaseFunction f1; public BusinessClass() { this.f1 = new LoggingFunction(new MyBusinessFunction()); } public final void doFunction() { f1.execute(); } } A call to doFunction will log this:
Entering function Initializing some variables Starting algorithm One step forward One step forward ... Ending algorithm Cleaning some mess Exiting function