Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java design, how do I avoid passing object down the hierarchy?!? Impossible?

Tags:

java

oop

generics

I have a number of classes, please allow me to introduce them and then ask my question at the end:

I have a container class which contains two objects in a composite relationship:

public class Container{

    A a;
    B b;

    public someMethod(){
        a.getC().myMethod(b);
    }
}

A and B are superclasses (or Interfaces), with subtypes that can also be the type held in the composite relationship.

A contains a member of (interface) type C:

public class A{
   C c;
}


public interface C{
    public void myMethod(B b);
}

public class D implements C{
    public void myMethod(B b){
        //This code will modify the state of object b, in class Container.
        b.changeState();
    }
}

public class E implements C{
    public void myMethod(B b){
        //This code will modify the state of object b, in class Container.
        b.changeState();
    }
}

My problem is that I wish to modify the state of object b from a method starting in the container class, which eventually calls code down the hierarchy, to classes D and E- calling myMethod() via dynamic binding. I want to do this because I am going to use polymorphism to run the correct myMethod() (depending on whether the type of object is D or E) and I wish to do this, rather than write IF statements.

So my problem is that it seems very bad continually passing the instance of object b down the class hierarchy to myMethod, so that I can run b-specific code to modify the state of b. Is there anything else I can do to modify b from d and e (collectively known as c)?

I can get this to work using just interfaces but without using generics- but when I added generics i had problems with types and that made me start to think if my whole design was flawed?

EDIT: I could probably do this easily just by using IF statements- but I wanted an elegant solution using polymorphism of classes D and E.

like image 482
user997112 Avatar asked Dec 05 '25 10:12

user997112


1 Answers

First of all, if I understood your question correctly, no instance of B is being "passed down" in your code. Dynamic dispatch will simply cause the myMethod() implementation in the actual type of a to be called with an instance of B as argument.

While it may be tedious to have to write the argument explicitly every time you implement myMethod(), there's nothing wrong with it.

The alternative is to give each subclass/implementation of A an attribute of type B. In this case, however, you would have to pass your B instance down the chain of constructors to the class that actually has your B attribute.

Your code would become:

public class A{
  C c;

  public A(C c) {
    this.c = c;
}


public interface C{
    public void myMethod(B b);
}

public abstract class CC {
  protected B b;

public CC(B b) {
  this.b = b;

public class D extends CC implements C {
    public D(B b) {
      super(b);
    }
    public void myMethod(){
        b.changeState();
    }
}

public class E extends CC implements C {
    public E(B b) {
      super(b);
    }
    public void myMethod(){
        b.changeState();
    }
}

And then somewhere, e.g. in Container's constructor:

b = new B();
a = new A(new E(b));
like image 178
Nicola Musatti Avatar answered Dec 07 '25 22:12

Nicola Musatti



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!