保持课程的最佳方法

时间:2013-08-05 07:40:04

标签: java software-design

假设我有一个类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.

      }
 }

现在开放一些选项,

1。将source存储为实例变量,但不要在cosntructor中传递它。

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.

2。再次指定来源&amp;不要将它存储为实例变量:

dfs.printPath(10,  source == 5)
Disadvantage: Redundant parameter passing,

3。添加另一个构造函数。

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
      }
 }

缺点:

引入一个额外的实例变量。对于新源,将创建新对象。这意味着为新源创建一个新对象。 字段源的值在每次调用时都是非常不同的,并且无法使其成为实例变量。

请建议我一个良好的代码维护方法。

谢谢,

2 个答案:

答案 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,它可以采用DFSResultsource并填充结果。 DFS不应该知道来源,而只知道如何将其结果存储在DFSResult个实例中。

稍后,您可能希望写入不同的来源。因此,最好将DFSResultWriter的方法放在接口中,并为每种源类型创建不同的实现。也许甚至Source可能会成为一个界面,并且您有Source的不同实现。

所以Source可以有一个实例方法:

source.writeDFSResult(DFSResult dfsResult)