我的一般问题是何时将争论传递给构造函数以及何时将其传递给 一个班级的方法。 通常,对象是“数据”+“作用于数据的方法”。
我有一些选项来设计一个名为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
}
}
答案 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
是不可变的,并且为每个方法调用传递它会很麻烦,因此最好使它成为构造函数参数。一些优点:
g
简而言之,当您知道某些内容不会改变为类的定义时,请将其作为构造函数参数。有使用这些实例变量的方法。当你知道某些事情可以改变时,请使用Setters。
答案 1 :(得分:0)
这是一个逻辑问题。当您设计类以使类的对象需要特定数据有效时,必须在构造函数中提供数据。您还应该使用assert
检查对象是否实际传递。
但您可以选择来设计您的课程,以便稍后添加数据。这取决于你打算如何使用你的课程 - 你应该为它的用户设计你的课程。
顺便说一句,你在帖子中评论“多态性代价高昂”。不,如果多态性是为您完成工作的,那么它并不昂贵。这取决于你的意思是什么样的多态性。答案 2 :(得分:0)
我个人更喜欢选项4.没有构造函数或最小构造函数使单元测试更容易测试类。
同样在大型项目中,我更喜欢创建仅保存参数的新类,然后使用这样的类作为参数。如果在很多地方传递相同的参数,则可以更轻松地在以后进行更改而无需更改所有方法。