• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

replacement for alternative design pattern

 
Ahmed Basheer
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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?
 
Ahmed Basheer
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Ahmed Basheer
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 171
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think this is what you want. Take a look at the "Strategy" and "Bridge" patterns.



Geoffrey
 
Ahmed Basheer
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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();
}
}
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic