繁体   English   中英

在这种情况下我应该使用什么样的设计?

[英]What kind of design shall i use in this scenario?

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

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帮助]

注意:改变上面的设计很好,但如果可能的话,一个小示例代码是值得赞赏的。

这个答案在很大程度上取决于您在本节中的操作:

所以最后,当我得到一个 Node b 时,我想访问它的属性(NodeA 或 NodeB),我知道这是不可能的,因为多态性不能那样工作。

就个人而言,我建议您使用Strategy Pattern 这样做的目的是有一个通用的方法,比如visit (它可以驻留在你的Node接口中,或者甚至可以创建一个IVisitable接口(或类似的东西)。这个方法的目的是处理访问你的算法的方面。

因此,本质上,您可以委托访问节点时发生的事情。 如果您需要做一些特定的事情,让这个方法将visitor作为方法参数接收可能是有意义的,这样您的访问者就可以对节点本身的内容进行操作。

正如您所提到的,在这里可以使用访问者模式。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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