假设我有一个类DFS,它将Graph作为构造函数参数,source作为doDfs参数。
public class DFS {
final Graph g;
list path;
public DFS(Graph g) {
this.g = g;
}
public void doDfs(int source) {
// dfs computation
populate path.
}
}
现在将来我需要扩展这个类并添加另一个函数'printPathToSource'。
public class DFS {
final Graph g;
list path;
public DFS(Graph g) {
this.g = g;
}
public void doDfs(int source) {
// dfs computation
populate path.
}
public void printPathToSource(int vertex) {
// dfs computation
populate path.
}
}
现在开放一些选项,
public class DFS {
final Graph g;
list path;
int source; // <------ NOTE the new field.
public DFS(Graph g) {
this.g = g;
}
public void doDfs(int source) {
// dfs computation
populate path.
if (souce == null) {
this.source = source;
}
}
public void printPathToSource(int vertex) {
// dfs computation
populate path using this.source
}
}
DFS dfs = new DFS(graph);
// some code
dfs.doDfs(5);
// some code
dfs.doDfs(7);
// some code
dfs.printPath(10); // <-- cannot direct this function if it wants the output of 5 or 7.
dfs.printPath(10, source == 5)
Disadvantage: Redundant parameter passing,
public class DFS {
final Graph g;
list path;
int source; // <------ NOTE the new field.
public DFS(Graph g) {
this.g = g;
}
public DFS(Graph g, int source) {
this.g = g;
this.source = source;
}
public void doDfs() {
doDfs(this.source);
}
public void doDfs(source) {
// dfs computation
populate path.
}
public void printPathToSource(int vertex) {
// dfs computation
populate path using this.source
}
}
引入一个额外的实例变量。对于新源,将创建新对象。这意味着为新源创建一个新对象。 字段源的值在每次调用时都是非常不同的,并且无法使其成为实例变量。
请建议我一个良好的代码维护方法。
谢谢,
答案 0 :(得分:0)
重载printPathToSource()
?
public void printPathToSource(int vertex) {
this.printPathToSource(this.source, vertex);
}
public void printPathToSource(int source, int vertex) {
// PROFIT!
}
答案 1 :(得分:0)
看起来您的班级DFS
负责存储图表并对此图表进行一些计算,该图表独立于“源”(请参阅示例1 for doDFS(source))
但是班级不负责存储最终结果。所以,根据我的经验,我建议:尝试将你的课程分离,考虑每个班级的责任。
最终,我会有一个类DFSResult
,其中包含DFS计算的结果(如果列表/地图不够)和类DFSResultWriter
,它可以采用DFSResult
和source
并填充结果。 DFS
不应该知道来源,而只知道如何将其结果存储在DFSResult
个实例中。
稍后,您可能希望写入不同的来源。因此,最好将DFSResultWriter
的方法放在接口中,并为每种源类型创建不同的实现。也许甚至Source
可能会成为一个界面,并且您有Source
的不同实现。
所以Source
可以有一个实例方法:
source.writeDFSResult(DFSResult dfsResult)