我有两个课程如下:
public class A{
private String id ;
private SortedMap<String,B> answer = new TreeMap<String,B>();
private String text;
}
public class B{
private String id = null ;
private SortedMap<String,A> question = new TreeMap<String,A>();
private String text = null;
}
有没有办法可以从上面的类中删除循环依赖...?
答案 0 :(得分:4)
没有,但没有问题。
在JAVA中具有循环依赖性没有问题。如果你想在两个方向上遍历结构,那么拥有它们是很常见的。想想父母和孩子彼此了解的树,从而创建循环依赖。
垃圾收集器将检测循环依赖关系并处理此问题。
在两个构造函数中都存在循环依赖关系时会出现唯一的问题,这会导致堆栈溢出:)
答案 1 :(得分:1)
不,除非您删除其中一张地图。
答案 2 :(得分:1)
根据您所拥有的内容,您不需要两个课程。尝试使这个类更通用,你只需要一个。
public class AB {
private final String id ;
private final SortedMap<String,AB> answer = new TreeMap<String,AB>();
private final String text;
private final boolean isA; // if you need to know if its an A or B.
}
答案 3 :(得分:1)
如果你有两个相互引用的类,如果同时编译两个类,javac将解决这个问题:
file: dev/A.java
class A {
B b = null;
public A(B b)
{
this.b = b;
}
};
file: dev/B.java
package dev;
class B {
A a = null;
public B(A a )
{
this.a = a;
}
};
$ javac -d classes dev/A.java
dev/A.java:3: cannot find symbol
symbol : class B
location: class dev.A
B b = null;
^
dev/A.java:4: cannot find symbol
symbol : class B
location: class dev.A
public A(B b)
^
2 errors
$ javac -d classes dev/B.java
dev/B.java:3: cannot find symbol
symbol : class A
location: class dev.B
A a = null;
^
dev/B.java:4: cannot find symbol
symbol : class A
location: class dev.B
public B(A a )
^
2 errors`
但是如果你输入:
$ javac -d classes dev/A.java dev/B.java
它将解决循环编译器依赖。
答案 4 :(得分:1)
(这实际上是一个评论,但我没有足够的声誉点来做到这一点)
: - &gt;你为什么要这样做?
因为findbugs在模式中这样说:CD_CIRCULAR_DEPENDENCY:
此类与其他类具有循环依赖关系。这使得构建这些类很困难,因为每个类都依赖于另一个来正确构建。考虑使用接口来打破硬依赖。
也wikipedia说: ...在软件设计中较大的软件模块之间的循环依赖关系 被认为是一种反模式,因为它们的负面影响...... 循环依赖通常由经验不足的程序员引入......
答案 5 :(得分:0)
public class A{
private String id ;
private SortedMap<String,A> answer;
private String text;
}
public class B extends A{
}
如果您觉得需要,或者只是在A
中使用布尔字段答案 6 :(得分:0)
回顾上一个问题 - 您可以更改xml架构并为答案添加某种<nextquestion>
标记。那么等效的xml文档将是:
<decision>
<question id="0">
<questionText>What type is your OS?</questionText>
<answer id="0">
<answerText>windows</answerText>
</answer>
<answer id="1">
<answerText>linux</answerText>
</answer>
<answer id="2">
<answerText>mac</answerText>
</answer>
</question>
<question id="1">
<questionText>What are you looking for?</questionText>
<answer id="0">
<answerText>table</answerText>
<!-- NEW TAG HERE -->
<nextquestion refid="3" />
</answer>
<answer id="1">
<answerText>chair</answerText>
</answer>
<answer id="2">
<answerText>bed</answerText>
</answer>
<answer id="3">
<answerText>cloth</answerText>
</answer>
</question>
<!-- ALL QUESTIONS ARE CHILDREN OF ROOT WITH UNIQUE ID -->
<question id="3">
<questionText>Which color table you want?</questionText>
<answer id="0">
<answerText>green</answerText>
</answer>
<answer id="1">
<answerText>black</answerText>
</answer>
<answer id="2">
<answerText>pink</answerText>
</answer>
</question>
</decision>
您可能也希望使用 unique ids 作为答案,如果您想重复使用不同问题的答案(多对多关系),甚至可以再次使用模型)
你上课:
public class Question {
private int id;
private String text;
private Set<Answer> answers;
// ...
}
public class Answer {
private int id;
private String text;
private Question nextQuestion;
}
当然有一个循环依赖,但绝对需要从模型真实域中继承。
答案 7 :(得分:0)
尝试类似:
import java.util.*;
class Question {
Question(int id, String question) {
this.id = id;
this.question = question;
}
static void toString(Question question, StringBuffer sb, int indent) {
for(int i=0;i<indent;i++)
sb.append('\t');
sb.append(question.id).append(' ').append(question.question).append('\n');
for (Map.Entry<Integer, Answer> entry : question.answers.entrySet()) {
Answer answer = entry.getValue();
for(int i=0;i<=indent;i++)
sb.append('\t');
sb.append(entry.getKey()).append(' ').append(answer.answer).append('\n');
if (answer.question != null) {
toString(answer.question, sb, indent+2);
}
}
}
public String toString() {
StringBuffer sb = new StringBuffer();
toString(this,sb, 0);
return sb.toString();
}
int id;
String question;
SortedMap<Integer, Answer> answers = new TreeMap<Integer, Answer>();
}
class Answer {
Answer(int id, String answer) {
this.id = id;
this.answer = answer;
}
final int id;
final String answer;
Question question; // may be null
}
public class Main {
public static void main(String[] args) {
Question q0 = new Question(0, "What are you looking for?");
Answer a0 = new Answer(0, "table");
q0.answers.put(a0.id, a0);
a0.question = new Question(0, "Which color table you want?");
a0.question.answers.put(0, new Answer(0, "green"));
System.out.println(q0);
}
}