簡體   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