何时使用构造函数以及何时传入参数

时间:2013-08-05 06:48:59

标签: java design-patterns

我的一般问题是何时将争论传递给构造函数以及何时将其传递给 一个班级的方法。 通常,对象是“数据”+“作用于数据的方法”。

我有一些选项来设计一个名为DFS的类。以下哪个例子最适合定义?

选项1:在构造函数中传递的图,函数中的源。 高级:相同的DFS对象将与不同的源重用。

public class DFS {
   Graph g;
   public DFS(Graph g) {
     this.g = g;
   }

   public void doDfs(int source) {
     // dfs computation
   }
}

选项2:具有2个参数且没有多态性的构造函数 Disadv:对于每个新来源,需要构建新对象。

public class DFS {
    Graph g;
    int source;   

    public DFS(Graph g, int source) {
      this.g = g;
      this.source = source;
    }

    public void doDfs() {
      // dfs computation
    }
 }

选项3:重载构造函数 高级:解决我们所有的用例。 Dis:多态性很昂贵。

public class DFS {
   Graph g;
   int source;   

   public DFS(Graph g) {
     this.g = g;
   }

   public DFS(Graph g, int source) {
     this.g = g;
     this.source = source;
   }

   public void doDfs() {
      doDfs(source);
   }

   public void doDfs(int source) {
     // dfs computation
   }
}

选项4:没有构造函数

public class DFS {

    DFS() { }

    public void doDFS(Graph g, int source) {
      this.g = g;
      this.source = source;
      // dfs computation
    }
 }

3 个答案:

答案 0 :(得分:2)

当你有一些与类的操作/定义相关联的东西时,它意味着作为构造函数传递。这也意味着,非常希望将其作为immutable。例如:

public class DFS {
   final Graph g;
   public DFS(Graph g) {
     this.g = g;
   }

   public void doDfs(int source) {
     // dfs computation
   }
}

您知道,类DFS包含多个方法(每个方法都有自己的算法),可以找到图DFS的{​​{1}}。在这种情况下,您知道g是不可变的,并且为每个方法调用传递它会很麻烦,因此最好使它成为构造函数参数。一些优点:

  1. 每个方法调用都没有冗余参数。
  2. 如果您想进行一些内部缓存,可以这样做。这适用于所有内容都与已知实体相关:g
  3. 线程安全,无明确锁定。你需要安装者。
  4. 简而言之,当您知道某些内容不会改变为类的定义时,请将其作为构造函数参数。有使用这些实例变量的方法。当你知道某些事情可以改变时,请使用Setters。

答案 1 :(得分:0)

这是一个逻辑问题。当您设计类以使类的对象需要特定数据有效时,必须在构造函数中提供数据。您还应该使用assert检查对象是否实际传递。

但您可以选择来设计您的课程,以便稍后添加数据。这取决于你打算如何使用你的课程 - 你应该为它的用户设计你的课程。

顺便说一句,你在帖子中评论“多态性代价高昂”。不,如果多态性是为您完成工作的,那么它并不昂贵。这取决于你的意思是什么样的多态性。

答案 2 :(得分:0)

我个人更喜欢选项4.没有构造函数或最小构造函数使单元测试更容易测试类。

同样在大型项目中,我更喜欢创建仅保存参数的新类,然后使用这样的类作为参数。如果在很多地方传递相同的参数,则可以更轻松地在以后进行更改而无需更改所有方法。