【发布时间】:2010-10-10 03:10:21
【问题描述】:
上下文
每一条知识都必须有一个, 明确的,权威的代表 一个系统。
问题
- 该语句如何与直接在多个位置在一个类中设置私有成员变量的值相协调?
- 因为值不能有外部依赖关系,这有关系吗?
- 直接更改除访问器外其他地方有公共访问器的私有成员变量是否重复?
示例
考虑以下代码:
public class Line {
private boolean changed;
private double length;
private Point start;
private Point end;
public Line( Point p1, Point p2 ) {
this.start = p1;
this.end = p2;
this.changed = true;
}
public void setStart( Point p ) { this.start = p; this.changed = true; }
public void setEnd( Point p ) { this.end = p; this.changed = true; }
public Point getStart() { return this.start; }
public Point getEnd() { return this.end; }
public double getLength() {
if( this.changed ) {
this.length = start.distanceTo( end );
this.changed = false;
}
return this.length;
}
}
即使changed 变量从未公开(通过公共访问器或其他方式),同一行代码基本上重复了四次:this.changed = true(三次)和this.changed = false(一次)。同样,this.start 和 this.end 的赋值发生了多次。相对于:
public Line( Point p1, Point p2 ) {
setStart( p1 );
setEnd( p2 );
}
public void setStart( Point p ) { this.start = p; dirty(); }
public void setEnd( Point p ) { this.end = p; dirty(); }
public double getLength() {
if( isDirty() ) {
setLength( getStart().distanceTo( getEnd() ) );
clean();
}
return this.length;
}
更新后的代码非常相似,但删除了所有重复的赋值(假设 dirty() 和 clean() 使用访问器)。 (由于重复使用访问器方法进行赋值,构造函数中存在对 dirty() 的重复调用。)
问题不在于this.changed = true 是否更容易理解为dirty()。
澄清
问题在于this.variable = value 是否是“知识”,因此应该有一个一致使用的“单一、明确、权威的表示”:相应的访问器。因此一般情况:
public class C1 {
private Object v;
public C1() {
this.v = new C1();
}
public void m1() {
this.v = new String();
}
public void m2() {
System.out.println( this.v );
}
}
对比:
public class C2 {
private Object v;
public C2() {
setV( new C2() );
}
public void m1() {
setV( new String() );
}
public void m2() {
System.out.println( getV() );
}
private void setV( Object o ) { this.v = o; }
private Object getV() { return this.v; }
}
在C1中,变量v在多个地方直接赋值。在 C2 中,变量v 直接分配在一个位置。尽管在这两种情况下,v 都是完全私有的,但 C1 实现是否复制了“知识片段”?
【问题讨论】:
-
我对这个问题有点困惑。假设
dirty()和clean()是设置this.changed 的mutators,那么两者确实是相同的。没有理由担心他们的差异。如果您真的想讨论差异,尽管调用 mutators/accessors 只是将更多函数推入堆栈,这最终意味着更多 ASM 调用,因此执行时间更长。 -
@steven_desu:代码设计很少涉及计算汇编指令。从一次性的角度来看,
dirty()方法实际上更干净,并且比其他方法更可取。此外,现代 Java 运行时具有方法内联,因此,就运行时而言,它没有任何区别。