简体   繁体   中英

What kind of design shall i use in this scenario?

I am new to designing softwares, and I am trying to build a Tree like struct.
I have an empty interface like this:

interface Node{
}

Two classes NodeA and NodeB implement this interface, and both have some specific attributes. Except that these are Nodes, they dont have anything common in them.

class A implements Node {
    public String a;
    public A(String a){
       this.a = a;
    }
}

class B implements Node {
    public int a = 5;
    public String z = "xyz";

    public B(int a,String z){
         this.a = a;
         this.z = z;
    }
}

I have aa class Parse that creates instances of the above classes , depending on certain conditions.

class Parse {
    List<Boolean> l;
    private static int i=0;
    Parse(List<Boolean> l){
        this.l = l;
    }

    private Node parseA() {
        return new A(/* param */); // Assume some parameters here
    }

    private Node parseB() {
        return new B(/* param */); // Assume some parameters here
    }

    private boolean getNextState(){
        return l.get(i++);
    }

    public Node parse(){
        boolean x = getNextState();
        if(x){
            return parseA();
        }
        else{
            return parseB();
        }
    }
}

Driver class:

public class Test {
    public static void main(String[] args) {
        List<Boolean> l = Arrays.asList(true,false); // so on...
        Parse p = new Parse(l);
        Node b = p.parse();  // not sure if its NodeA or NodeB
    }
}

After building the tree, i am planning to use visitor pattern to retrieve some attributes and do some operations.

So at last, when i get a Node b , i want to access its attributes (of NodeA or NodeB ), which i know cant be done as Polymorphism doesnt work that way.

I think that using instanceof ladder and type-casting arent proper solutions to it.
Sorry for this silly problem, but being new to designing, i aint getting what to do next.

How shall one solve this design problem? can anyone share a small design structure for this, assuming that this structure will grow bigger and have ample of different nodes. [may be Java Generics help here]

Note: chaning above design is fine,but if possible, a small sample code is appreciated.

This answer depends heavily on what you do in this section:

So at last, when i get a Node b, i want to access its attributes (of NodeA or NodeB), which i know cant be done as Polymorphism doesnt work that way.

Personally, I would suggest you use the Strategy Pattern . The aim of this would be to have a common method, say, visit (which could reside within your Node interface, or maybe even create an IVisitable interface (or something along those lines). The aim of this method would be to handle the visit aspect of your algorithm.

So in essence, you would delegate what happens when you visit the node. If you need to do something specific, it might make sense to have this method take in the visitor as a method parameter so that your visitor can operate on the content of the node itself.

As you've mentioned Visitor pattern can be used here.

interface Node {
    <T> T accept(NodeVisitor<T> visitor);
}

class A implements Node {
    public String a;
    public A(String a){
       this.a = a;
    }

    @Override
    public <T> T accept(NodeVisitor<T> visitor) {
        return visitor.visit(this);
    }
}

class B implements Node {
   public int a = 5;
   public String z = "xyz";

   public B(int a,String z){
        this.a = a;
        this.z = z;
    }

    @Override
    public <T> T accept(NodeVisitor<T> visitor) {
        return visitor.visit(this);
    }
}

interface NodeVisitor<T> {
    T visit(A node);
    T visit(B node);
}

Then define particular operation by implementing corresponsing visitor:

    NodeVisitor<Integer> visitor = new NodeVisitor<Integer>() {
        @Override
        public Integer visit(A node) {
            // TODO do something with A node
            return null;
        }

        @Override
        public Integer visit(B node) {
            // TODO do something with B node
            return null;
        }
    };

and just call accept:

Node node = ...;
Integer result = node.accept(visitor);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM