且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

泛型在访客模式中过度杀伤

更新时间:2023-12-01 18:29:28

If you really want to refactor, my recommendations would be like this:

Use a data container type for passing parameters and return values. In my comment I recommended to use a VisitorParameterType and a VisitorReturnType, but since there is much overlapping, you can use one common datatype.

public class VisitorData {
    private A a;
    private B b;
    private C c;
    private D d;
    // one constructor for each type
    private VisitorData(A a) {
        this.a = a;
    }
    // getters, setters
}

The Visitor:

public interface RobotVisitor {
public VisitorData visitHead(Head p, VisitorData arg);
public VisitorData visitNeck(Neck p, VisitorData arg);
public VisitorData visitShoulder(Shoulder p, VisitorData arg);
public VisitorData visitArm(Arm p, VisitorData arg);
....
// A lot of methods.
}

The base class:

public abstract class BodyPart {
// A lot of fields, so it is not simple to convert this to an interface.

public abstract VisitorData accept(RobotVisitor visitor, VisitorData arg);
}

One subclass:

public class Arm extends BodyPart {
    // Some fields, getters and setters...

    public VisitorData accept(RobotVisitor visitor, VisitorData arg) {
        return visitor.visitArm(this, arg);
    }
}

The main achievement with this was not the introduction of generics, but to refactor your code to implement a uniform visitor pattern, which is much easier to follow. Also, you got rid of the nasty unchecked castings.