Here is some of my Java code
public List<OBJ> a = new ArrayList<OBJ>();
public String A;
public String B;
public String C;
for (OBJ o : a) {
// .... TODO
}
So I have an interface OBJ and there are three objects that implements OBJ say X, Y, Z. So I store X/Y/Z objects in List a. Now say that I want to go through the loop and if o is of instance X store X.value in A, if Y store Y.value in B, and if Z store Z.value in C. So the problem is really how do you figure out what object type o is (X,Y,Z) to store their values in the right string.
NOTE: I want to use the Visitor pattern or something like it, but I don't really have a firm grasp of it so I'm asking for your help.
This means NO Instanceof(s) or Type Casts and NO Dedicated Methods like
interface OBJ {
void blah();
}
class X implements OBJ {
public void blah();
} // etc
Thanks! I really want to get this import aspect of software engineering down!
Hey wow thanks for the detailed and fast responses, but my situation is a bit more complicated and sorry I didn't add this before.
So String A, B, C are actually housed in another class like
class ARGH {
public List<OBJ> a = new ArrayList<OBJ>();
public String A;
public String B;
public String C;
//invisible constructor here
public String toString () {
for (OBJ o : a) {
// .... TODO
}
return "some string"
}
}
public void main (String[] args) {
ARGH argh = new ARGH();
// Setup some X, Y, Z objects and their values here
String D = argh.toString();
// Do something to D
}
So the Strings and List are actually not global variables so I don't think this would work:
ObjVisitor v = new ObjVisitor() {
@Override
public void visit(X x) {
A = x.value();
}
// And so on.
}
I am assuming I have to somehow pass in the String A, B, C into the visit method but I don't know how to do that and still stay with The Visitor Pattern.
In a nut-shell you'd do like this:
ObjVisitor with one visit-method for each type.accept(ObjVisitor v) to OBJ.accept(ObjVisitor v) { v.visit(this); } to each OBJ implementation.o.accept(yourVisitorImpl) in the loop.You did indeed get some code from Bringer128. I elaborated a bit and added the String-stuff.
import java.util.*;
interface OBJ {
String accept(ObjVisitor v);
}
interface ObjVisitor {
String visit(X x);
String visit(Y y);
String visit(Z z);
}
class X implements OBJ {
public String accept(ObjVisitor v){ return v.visit(this); }
}
class Y implements OBJ {
public String accept(ObjVisitor v) { return v.visit(this); }
}
class Z implements OBJ {
public String accept(ObjVisitor v) { return v.visit(this); }
}
Usage:
class Test {
public static void main(String[] args) {
List<OBJ> objs = Arrays.asList(new Z(), new X());
ObjVisitor toStringVisitor = new ObjVisitor() {
public String visit(X x) { return "X object"; }
public String visit(Y y) { return "Y object"; }
public String visit(Z z) { return "Z object"; }
};
String result = "";
for (OBJ o : objs)
result += o.accept(toStringVisitor) + "\n";
System.out.println(result);
// Prints
// Z object
// X object
}
}
An alternative (perhaps better approach) would be to let the visitor implementation maintain a StringBuilder, let the visit-methods return void, and after the loop just call stringVisitor.getCurrentString() or something like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With