在这种情况下我应该使用什么样的设计?
What kind of design shall i use in this scenario?
我是设计软件的新手,我正在尝试构建一个类似结构的树。
我有一个像这样的空界面:
interface Node{
}
两个classes 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
可以根据特定条件创建上述 classes 的实例。
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
}
}
构建树后,我打算使用访问者模式来检索一些属性并进行一些操作。
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.
我认为使用 instanceof
梯子和 type-casting 不是正确的解决方案。
很抱歉这个愚蠢的问题,但作为设计新手,我不知道下一步该做什么。
如何解决这一设计问题?任何人都可以为此分享一个小的设计结构,假设这个结构会变得更大并且有足够的不同节点。 [可能 Java Generics
在这里帮忙]
注意:改变上面的设计很好,但如果可能的话,一个小的示例代码是值得赞赏的。
此答案在很大程度上取决于您在本节中的操作:
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.
就我个人而言,我建议您使用 Strategy Pattern。这样做的目的是拥有一个通用方法,例如 visit
(它可以驻留在您的 Node
界面中,或者甚至可以创建一个 IVisitable
界面(或类似的东西) . 此方法的目的是处理算法的 visit 方面。
所以本质上,您将委托访问节点时发生的事情。如果您需要做一些特定的事情,让这个方法将 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);
我是设计软件的新手,我正在尝试构建一个类似结构的树。
我有一个像这样的空界面:
interface Node{
}
两个classes 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
可以根据特定条件创建上述 classes 的实例。
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
}
}
构建树后,我打算使用访问者模式来检索一些属性并进行一些操作。
So at last, when i get a
Node b
, i want to access its attributes (ofNodeA
orNodeB
), which i know cant be done as Polymorphism doesnt work that way.
我认为使用 instanceof
梯子和 type-casting 不是正确的解决方案。
很抱歉这个愚蠢的问题,但作为设计新手,我不知道下一步该做什么。
如何解决这一设计问题?任何人都可以为此分享一个小的设计结构,假设这个结构会变得更大并且有足够的不同节点。 [可能 Java Generics
在这里帮忙]
注意:改变上面的设计很好,但如果可能的话,一个小的示例代码是值得赞赏的。
此答案在很大程度上取决于您在本节中的操作:
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.
就我个人而言,我建议您使用 Strategy Pattern。这样做的目的是拥有一个通用方法,例如 visit
(它可以驻留在您的 Node
界面中,或者甚至可以创建一个 IVisitable
界面(或类似的东西) . 此方法的目的是处理算法的 visit 方面。
所以本质上,您将委托访问节点时发生的事情。如果您需要做一些特定的事情,让这个方法将 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);