[英]Is variable initialization/assignment statement is a single operation or more?
[英]Variable value assignment operation duplication
來自務實的程序員 :
每一段知識都必須在系統中具有單一,明確,權威的表示。
請考慮以下代碼:
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
的賦值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
is直接分配在單個點中。 即使在這兩種情況下, v
都是完全私有的,C1實現是否會復制“知識”?
如何在多個位置的整個類中直接設置私有成員變量的值來協調該語句?
有一個私有成員變量。 因此,只有一個代表。 更改此表示的語句本身不是表示形式。 具有訪問/更改表示的多個語句與具有多個表示的不同。
是否重要,因為該值不存在外部依賴性?
沒有。
是否重復直接更改除訪問者之外的其他地方具有公共訪問者的私有成員變量?
沒有。
這並不一定意味着盡管這樣做是個好主意。
在您的示例中,選擇是直接訪問和更新“臟”標志還是通過輕量級私有方法執行此操作。 IMO,這歸結為一種價值判斷,即哪種方法為您提供更易讀的代碼。 我的感覺是兩種方法之間幾乎沒有區別,至少在這種情況下。 在其他情況下,使用內部方法訪問/更新從未公開的私有狀態可能會有更強的理由。
如果狀態需要暴露在類之外,則有一個強有力的例子可以將變量聲明為私有,並為其他類提供getter和setter。 如果已經聲明了那些getter和setter,那么你可以創建一個(弱)情況,類本身應該使用它們。
對於那些擔心Java中的getter和setter的效率或其他方面的人來說,它可能對性能沒有任何影響。 現代JVM中的JIT編譯器幾乎肯定會內聯方法,如clean()
, dirty()
和isDirty()
導致機器指令等同於直接獲取和設置變量的情況。 實際上,最新的JIT編譯器甚至可以推斷出非最終的公共方法,因為他們可以推斷出這些方法不需要發送。
像dirty()
這樣的方法比this.changed = true
具有更多的語義含義。 如果你決定要以不同的方式處理臟跟蹤,你只需要改變一個地方---從其他代碼的角度來看(即使它們都在同一個類中),它仍然更有意義(並且更容易讓讀者掌握)。
簡而言之,我建議使用dirty()
而不是this.changed = true
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.