Refactoring: Sync. to Async. (An Object Oriented Approach)

Let’s get back to the refactoring : sync to async problem. If you don’t know the scenario, then you will probably want to read this article first.

The purpose of this article is to prove that classical object oriented techniques would also be sufficient for solving this particular problem.

In fact, some people have been talking about AOP as if it is a total revolution and it provides radical solutions for the problems that have never been resolved before!

I am personally against those kind of ideas and believe that the main idea behind AOP is not to derive solutions to problems we haven’t been able to solve so far. I believe the idea is to improve the solutions to the problems we have dealed with.

Let’s step back to the example in previous article and solve the problem using object oriented techniques.

To do that, we are going to use the “Decorator” design pattern. However, for this approach to become a valid one, the class we are going to decorate should have been created in such a way that it is based on some carefully designed abstractions and coded on to an interface, not an implementation!

If you look through the code, you may notice that the class Foo is coded on top of an implementation rather than an interface.

In fact, it is this way; because my intention was just to introduce the problem and indicate how AOP could become a solution for that. Most of the time, a good programmer would depend on abstractions and program on top of interfaces, rather than implementations!

Hence, please assume that Foo implements IFoo and IFoo simply consists of the same methods as we have in Foo. Moreover, assume that all the other types depend on IFoo instead of Foo.

Caution: Notice that we are making the design in “the other way around”, this is not a good design practice! We should have identified the interface before and implementation later, however, I am trying to fit one problem that is subject for one particular article to another article, this was not my intention, hence there should be no problem at all, for this specific case.

By using Decorator pattern, we will decorate instances of Foo in such a way that they will represent an “asynchronous” behaviour rather than a “synchronous” one. AsynchronousFoo class will decorate Foo and simply delegate calls to an instance of Foo, but in an asynchronous way.

package ali.test;

public interface IFoo {

public void performFirstTask() throws InterruptedException;

public void performSecondTask() throws InterruptedException;

}

package ali.test;

public class Foo implements IFoo {

public Foo()

{

}

public void performFirstTask() throws InterruptedException

{

Thread.sleep(3000);

System.out.println(“Foo : the first complex task has been completed…”);

}

public void performSecondTask() throws InterruptedException

{

Thread.sleep(3000);

System.out.println(“Foo : the second complex task has been completed…”);

}

}

package ali.test;

public class AsynchronizedFoo implements IFoo {

private Foo foo;

public AsynchronizedFoo(Foo f)

{

this.foo = f;

}

@Override

public void performFirstTask() throws InterruptedException {

// TODO Auto-generated method stub

Thread t = new Thread()

{

public void run()

{

try {

foo.performFirstTask();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

t.start();

}

@Override

public void performSecondTask() throws InterruptedException {

// TODO Auto-generated method stub

Thread t = new Thread()

{

public void run()

{

try {

foo.performSecondTask();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

t.start();

}

}

import ali.test.AsynchronizedFoo;

import ali.test.Foo;

import ali.test.IFoo;

public class Program {

public static void main(String[] args) throws InterruptedException

{

System.out.println(“Foo obj. will complete a complex task.”);

IFoo f = new AsynchronizedFoo(new Foo());

f.performFirstTask();

f.performSecondTask();

System.out.println(“end of sequence”);

}

}

Now that we have resolved this issue in two different ways; using an object oriented approach and an aspect oriented approach, you can select and use one of them, depending on the conditions.

Tags: ,

Leave a Reply