Meaningless Drivel is fun!*
The moose likes Java in General and the fly likes replacement for alternative design pattern Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "replacement for alternative design pattern" Watch "replacement for alternative design pattern" New topic
Author

replacement for alternative design pattern

Ahmed Basheer
Ranch Hand

Joined: Apr 15, 2004
Posts: 77
I have a static variable in the abstract class ( a target object) which is set through satic set method. The derived classes which are many use this static target object to invoke method on the target object. The problem is I have to move away from static design, because same application can have mutiple instance in a single JVM in which case each instance of the application have different target object. Having static target object means all instances are sharing one object and that is problem.

Should I refactor this and use different pattern. I could use target object as a parameter to every call in derived classes but that doesn't seem a elegant solution. Any suggestion.

-Basheer

Here is the code example.

public abstract class base
{
public static invoker mTarget;
public static void setInvoker(invoker aTarget){
mTarget = aTarget;
}
abstract void call();
abstract void call2();
}
public class derived1 extends base{
void call(){
mTarget.method1();
}
void call2(){
mTarget.method2();
}
}
public class derived2 extends base{
void call(){
mTarget.method1();
}
void call2(){
mTarget.method2();
}
}
public class invoker
{
public static void main(String[] args){
new derived1().call();
new derived2().call2();
}
void method1(){
}
void method2(){
}
}
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
A few choices come to mind. Without knowing more of your system design I can't guess which will work for you.

Remove 'static' from the invoker variable and setInvoker method. Now somebody has to call setInvoker on every new instance of the derived class. Don't know who that somebody might be.

Make each new instance of the derived class just create its own invoker instance. Don't know what else the invoker needs to know about.

Make each new instance of the derived class get its invoker from a pool or map somewhere. Don't know how it would decide which one it should use.

Your idea: Pass the invoker to any method that needs to use it. I think I'd prefer a set over this but would have to see it in action to be sure.

What else have you thought about?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Ahmed Basheer
Ranch Hand

Joined: Apr 15, 2004
Posts: 77
The invoker is one per instance , hence two for two instances of applications in one one jvm. so derived classes can't create their own instance of invoker.
If there are two instances of app there will be a pair of invoker,base,derived1, derived2 instances.


I am thinking about using the base and derived class as a inner classes to invoker. That is one possible solution but that would breake the cohesiviness of the invoker. Also every new derived class means touching the invoker class. But I see that inner classes( in this case base, derived1, derived2) will have a access to the instance of enclosing class, invoker. BTW thanks for your response. I am still thinking..

Basheer
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'm not sure what two instances of an application in a JVM means. Are you in a J2EE container or something that loads and runs applications?
Ahmed Basheer
Ranch Hand

Joined: Apr 15, 2004
Posts: 77
Yes I am in a tomcat container that runs different instances of same application in different threads but under one JVM instance.

You mentioned earlier that derived classes can find invoker from the map. Were you thinking of maintaing static map of invoker with thread id as a key?
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Cool problem. I'm not familiar with the guts of running two copies of an app inside a container. Do they have any per-instance configuration or identifiers? Guess I'm fishing for some key to use in a static map.

Are they loaded by separate class loaders? If so you might already get two copies of static variables. Have you confirmed that both app instances share static values?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Tomcat uses one classloader per web application, so yes, per default every web application will get it's own copy of a class, and therefore its static variables.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ahmed Basheer
Ranch Hand

Joined: Apr 15, 2004
Posts: 77
I verified that that two instances are two modules " so called web service modules" and will only share one copies of static variables.

The instance id's are different and yes I could use that as a key in the static map. In this problem two invoker objects will have two unique instance id's as a key's.

How do you like my idea of inner classes. Inner classes automatically have reference to the enslosing class. Am I being naive here in thinking in terms of inner classes. I have been reading chapter of Inner classes in "Thinking in Java" book. Inner classes are much more powerful thatn I had been thinking.

-Basheer
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Well, the last two posts disagree so I'm a bit confused.

I'm also not quite sure of the requirement. See if this is right: There is one Invoker instance per application instance. All the objects in app instance A should use Invoker X, all the objects in app instance B should use Invoker Y.

I don't think I see how to use inner classes to solve that.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ahmed Basheer:
I verified that that two instances are two modules " so called web service modules" and will only share one copies of static variables.


How did you verify that? How is your webapplication deployed to Tomcat?
Geoffrey Falk
Ranch Hand

Joined: Aug 17, 2001
Posts: 171
    
    1
I think this is what you want. Take a look at the "Strategy" and "Bridge" patterns.



Geoffrey


Sun Certified Programmer for the Java 2 Platform
Ahmed Basheer
Ranch Hand

Joined: Apr 15, 2004
Posts: 77
I think this is what you want. Take a look at the "Strategy" and "Bridge" patterns.

Thanks Geoffrey. I know this solution. It gets ungly if you have more tha two derived classes that you have to instantiate each derived class with invoker.

I have been looking the solution in terms of inner classes but I failed to detach the invoker with other classes. Take a look at this solution. Invoker is implicit in the base and derived classes. But I don't like this as I said I can't detach invoker from the rest of the classes while keeping invoker object still implicit in the derived classes.

public class invoker
{

void method1()
{
System.out.println("In method1");
}
void method2()
{
System.out.println("In method2");
}


abstract class base1
{
abstract void call1();
abstract void call2();
}

public class derived1 extends base1
{
void call1()
{
method1();
}
void call2()
{
method2();
}
}
public class derived2 extends base1
{
void call1(){
method1();
}
void call2(){
method2();
}
}

public base1 getDerived1()
{
return new derived1();
}
public base1 getDerived2()
{
return new derived2();
}

public static void main(String[] args)
{

invoker inv= new invoker();
base1 b1 = inv.getDerived1();
base1 b2= inv.getDerived2();
b1.call1();
b2.call2();
}
}
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: replacement for alternative design pattern
 
Similar Threads
Type Cast and reference problem
problem on constructors scjp1.4
Please somebody explain
ClassCastError vs. Compilation Error
means Polymorphic method call