[英]What kind of design shall i use in this scenario?
我是设计软件的新手,我正在尝试构建一个类似结构的树。
我有一个像这样的空界面:
interface Node{
}
两个类NodeA
和NodeB
实现了这个接口,并且都有一些特定的属性。 除了这些是节点之外,它们之间没有任何共同之处。
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
,我想访问它的属性(NodeA
或NodeB
),我知道这是不能完成的,因为多态性不能那样工作。
我认为使用梯子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.