Variable Value Duplication Operation

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”?

+1
source share
2 answers

How is this statement consistent with directly setting the value of a private member variable in the entire class in several places?

There is one private member variable. Therefore, there is only one idea. Statements that alter this view are not representations themselves. The presence of several operators that have access / change the view does not coincide with multiple views.

Does it matter, since there can be no external values ​​for the value?

No.

Is this duplication to directly modify private member variables that have public accessors in places other than accessories?

No.

This does not necessarily mean that it is a good idea.

In your example, the choice is between accessing and updating the dirty flag directly or using light private methods. IMO, it comes down to a value judgment as to which approach gives you more readable code. And I feel that there is little difference between the two approaches, at least in this case. In other cases, there may be a stronger example of using internal methods to access / update a private state that is never displayed.

If the state should be open outside the class, then there is a strong argument for declaring private variables and providing getters and setters for use by other classes. And if these getters and setters were declared, you can make a (weaker) case where the class itself should use them.

For those people who are concerned about the performance or otherwise of getters and setters in Java, there is a chance that this will not affect performance. The JIT compiler in a modern JVM will almost certainly include methods such as clean() , dirty() and isDirty() , leading to machine instructions, equivalent to the case when you get and set variables directly. In fact, the latest JIT compilers will even include non-final public methods when they can deduce that the methods do not need to be sent.

+3
source

A method like dirty() has more meaning than this.changed = true . If you ever decide that you want to handle dirty tracking differently, you only need to change one place - and from the point of view of another code (even if everything is in the same class) it is even more meaningful (and easier for the reader to understand).

In short, I recommend using dirty() instead of this.changed = true .

+1
source

All Articles