在这种情况下我应该使用哪种设计?

时间:2020-02-28 08:08:51

标签: java design-patterns software-design

我是设计软件的新手,我正在尝试构建类似struct的Tree。
我有一个空的界面,像这样:

interface Node{
}

两个类NodeANodeB实现了此接口,并且都具有一些特定的属性。除了这些是节点外,它们中没有任何共同点。

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;
    }
}

我有一个class Parse,可以根据特定条件创建上述类的实例。

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();
        }
    }
}

驱动程序类:

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
    }
}

构建树之后,我打算使用访问者模式来检索一些属性并执行一些操作。

因此,最后,当我得到Node b时,我想访问它的( NodeANodeB),我知道无法做到,因为多态不会 这样工作。

我认为使用instanceof梯形图并对其进行类型转换并没有适当的解决方案。
很抱歉这个愚蠢的问题,但是对设计来说是新手,我没有下一步要做的事情。

如何解决这一设计问题?任何人都可以为此共享一个小型设计结构,前提是该结构将变得更大并且具有足够多的不同节点。 [这里可能Java Generics有帮助]

注意:更改上面的设计是可以的,但如果可能的话,建议您使用少量示例代码。

2 个答案:

答案 0 :(得分:1)

此答案在很大程度上取决于您在本节中所做的事情:

因此,最后,当我得到一个节点b时,我想访问它的( NodeA或NodeB),我知道无法完成,因为多态性无法正常工作 这样。

我个人建议您使用Strategy Pattern。这样做的目的是要有一个通用的方法,例如visit(可以驻留在您的Node接口中,甚至可以创建一个IVisitable接口(或类似的方法)该方法的目的是处理算法的 visit 方面。

因此,从本质上讲,您将委托访问该节点时会发生什么。如果您需要做一些特定的事情,让此方法接受visitor作为方法参数可能很有意义,以便您的访问者可以对节点本身的内容进行操作。

答案 1 :(得分:1)

正如您所提到的,可以在此处使用“访客”模式。

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);
}

然后通过实现相应的访问者来定义特定操作:

    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;
        }
    };

,然后致电接受:

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