Context
From the Pragmatic Programmer :
Each piece of knowledge must have a single, unambiguous, authoritative system.
Questions
- How is this statement consistent with directly setting the value of a private member variable in the entire class in several places?
- Does it matter, since there can be no external values for the value?
- Is there duplication for directly modifying private member variables that have public accessors in places other than accessories?
Example
Consider the following code:
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; } }
Even though the changed variable is never displayed (through public applications or otherwise), the same line of code is essentially repeated four times: this.changed = true (three times) and this.changed = false (once). Similarly, the assignment of this.start and this.end occurs several times. Unlike:
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; }
The updated code is very similar, but duplication of all assignments is deleted (suppose dirty() and clean() use accessors). (There is a duplicate call to dirty() in a constructor that did not exist before, due to the reuse of access methods for assignment.)
The question is not whether this.changed = true easier to understand as dirty() .
Explanation
The question is whether this.variable = value “piece of knowledge” and therefore should have a “single, unambiguous, authoritative representation” that is used sequentially: the corresponding accessor. So the general case:
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 ); } }
vs
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; } }
In C1, the variable v directly assigned in several places. In C2, the variable v directly assigned in one place. Although v completely closed in both cases, does the C1 implementation implement a “piece of knowledge”?