Reflection Example Part 6

in the previous example, the application will work however it’s tied to target object types and worker thread’s constructor. we can make it loosely coupled in a way that releases the application from these constraints and makes that flexible to decide later in running time about what Thread worker types might come in and also we can add different workerThread in future without changing the main logic. also, another good tip is reflection is Slower than regularly compiled programming, we need to decrease the use of reflections as much as possible. below is the solution:

Interface TaskWorker:


package com.navid.practice.reflection.newsrc.worker2;

/**
* by using this class
* 1. we can have different worker as much as we want
* 2. the worker's code doesn't need to have special constructor. -- more loosely coupled.
*
* @author Unknown_
*/
interface Taskworker extends Runnable{

/**
* do the actual task, so any thread could implement this.
* implement the threading triggering process.
* @param operation
* @param amount
*/
public void doWork();

/**
* setting a target for our worker thread implemenation. this target object will be an object reference to
* a BankAccount object or anything that is extended the bankAccount object.
* @param target
*/
public void setTarget(Object target);

}

then updating worker thread

AccountWorkerImproved


package com.navid.practice.reflection.newsrc.worker2;

import com.navid.practice.reflection.legacy.beans.BankAccount;
import com.navid.practice.reflection.legacy.beans.HighVolumeAccount;

/**
*
* @author Unknown_
*/
public class AccountWorkerImproved implements Taskworker {

private BankAccount bankAccount;

@Override
public void doWork() {

//decied if that's the BankAccount normal or HighVolume one, then trigger its thread.
Thread thread  = new Thread( HighVolumeAccount.class.isInstance(bankAccount)? (HighVolumeAccount)this.bankAccount : this);

thread.start();
}

@Override
public void setTarget(Object target) {

if(BankAccount.class.isInstance(target)){
this.bankAccount = (BankAccount) target;
}else
throw new IllegalArgumentException("Target object is not matching bankAccount class");
}

@Override
public void run() {
System.out.println("WorkerThreadImproved - start processing the account deposits ... ");
}

}

Executing the Scenario


package com.navid.practice.reflection.newsrc.worker2;

import com.navid.practice.reflection.legacy.beans.BankAccount;
import com.navid.practice.reflection.legacy.beans.HighVolumeAccount;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Unknown_
*/
public class ReflectionPractice2 {

public void startWork(String workerTypeName, Object workerTarget) {

try {

// providing the worker thread information.
Class<?> workerType = Class.forName(workerTypeName);

// since we don't have any additional constructor beside our worker thread default one, so we don;t need to get the target types
// and call it. insteda we cna use this ...
Taskworker taskWorker = (Taskworker) workerType.newInstance();

// the the rest is like reglar programming
taskWorker.setTarget(workerTarget);
taskWorker.doWork();

} catch (ClassNotFoundException | SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException ex) {
Logger.getLogger(ReflectionPractice2.class.getName()).log(Level.SEVERE, null, ex);
}

}

public static void main(String[] args) {

BankAccount bankAccount = new BankAccount("1234", 100);

new ReflectionPractice2().startWork("com.navid.practice.reflection.newsrc.worker2.AccountWorkerImproved", bankAccount);

HighVolumeAccount highVolumeAccount = new HighVolumeAccount();

new ReflectionPractice2().startWork("com.navid.practice.reflection.newsrc.worker2.AccountWorkerImproved", highVolumeAccount);
}

}

the output of our test is exactly the same as before, but we decrease the use of reflection and also make our design clearer and loosely coupled.

run:
BankAccount Object constructor 2
BankAccount Object constructor 1 
WorkerThreadImproved - start processing the account deposits ... 
HighVolumeAccount process all Daily Deposits.
HighVolumeAccount process all Daily Withrwals.
BUILD SUCCESSFUL (total time: 0 seconds)
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s