By Mahmoud M.Orabi
Introduction:
When using Eclipse for Java development, we need to go
through each method declaration at some points to see the implementation for
these methods. Eclipse has several usability advantages with quick key strokes
and proper hierarchy when navigating between super types. However, it is not
that usable when it comes to the upcast variables delectation, as in all cases
it will take us to the interface or abstract method definition
Pre-Requirements:
Download and use any eclipse with Java support from Eclipse
website at: http://www.eclipse.org/downloads/
Scenario Preparation:
Start a new Java project from File/New, and name it “org.usability.show”.
Create an interface ILogger, which is implemented by an
AbstractLogger. And this abstract logger is extended by a Logger class. Finally,
there is ExtendedLogger that extends Logger
The class implementations would be as follows:
ILogger:
public interface ILogger {
public void start();
public void end();
public void log(String... args);
}
AbstractLogger:
public abstract class AbstractLogger implements ILogger {
private boolean started= false;
private boolean done= false;
public AbstractLogger() {
this.started= false;
this.done= false;
}
public void start() {
this.started= true;
}
public void end() {
this.done= true;
}
public boolean isStarted(){
return this.started;
}
public boolean isDone(){
return this.done;
}
public void log(String... args) {
System.out.println(args);
}
}
Logger:
public class Logger extends AbstractLogger {
public void log(String... args) {
System.out.println("Start Logging");
super.log(args);
}
}
ExtendedLogger:
public class ExtendedLogger extends Logger {
public void log(String... args) {
System.out.println("My extended Logger");
super.log(args);
}
}
And then create a static class
that uses your methods. Let's name it LoggerTest:
public class LoggerTest {
public static void main(String[] args) {
ILogger myLogger=
new
Logger();
myLogger.log("Log1", "TesTLog");
doLog(myLogger);
doLog(new ExtendedLogger());
}
public static void doLog(ILogger logger){
logger.log("This is a test");
}
}
Usability testing Scenario:
- Open LoggerTest class.
- Right click on the method called
“myLogger.log”, and choose Open Declaration:
- This will take us to ILogger
definition, which is just a definition with now implementation:
However, in my definition, I created
an instance of “Logger,” but my upcast variable was an “ILogger”, so Eclipse
will assume that we will open the declaration for ILogger – not the Logger – even
if my instance is an instance of Logger.
Expected Usability Result:
When I need to navigate to “myLogger.log”
declaration, I would like to get navigated to the Logger#log method
declaration:
Challenges to apply the required usability changes:
This can be easily implemented
if the variable is defined at the scope of the method. For instance, in the
pre-mentioned example, the ILogger instance was defined in the same scope, so
we can track its required level of
abstraction from that point.
This will more difficult if the
instance is defined from a different scope. For example, if we receive the
value as an argument for a method. For example:
public void doLog(ILogger logger){
logger.log("This is a test");
}
In such place, this will make
it difficult to determine where to exactly go. This method can be used and have
any kind of ILogger passed.
For this, there could be two
recommendations:
1) Prompt the user where to go:
For our example, the user will
get prompted for choices: Logger, AbstractLogger, and ILogger. At least we can decide which one to go to. For
now, the workaround to do that is to accept that we will go to ILogger, and
then show its call hierarchy, and see which classes are using it. However, this
way is not that usable, as it will lead us to too many clicks. With the
proposed solution, we will only need to choose which class to navigate to.
2) Better handling during Debugging session:
When debugging,and stepping
into that method, we shall be able to hold the real-time instance for that
objects. When we choose open declaration, the Eclipse must be smart enough to
open the declaration for the active instance.
So, eclipse already has the
required information on the logger instance class. So, when trying to open the
declaration for logger#log, we must go to Logger#log definition.
And for example such as
follows:
Conclusion:
Eclipse “Open Declaration” is
one of the commonly used features in Eclipse. However, we have usability issues
when it comes to interface-oriented programming or abstraction. We are not able
to open the delectation of the actual object method declarations, which makes
it hard for several occasions,
especially when you are debugging.
No comments:
Post a Comment