变量值分配操作重复 [英] Variable value assignment operation duplication

查看:95
本文介绍了变量值分配操作重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 务实程序员


每条知识都必须有一个单一的,
明确,权威的

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.



问题




  • 该语句与直接在多个地方的整个类中直接设置私有成员变量的值相符吗?

  • 这有关系吗,因为对该值没有外部依赖关系?

  • 直接更改除访问者之外在其他地方具有公共访问者的私有成员变量是否重复?

  • Questions

    • How is that statement reconciled with directly setting a private member variable's value throughout a class in multiple places?
    • Does it matter as there can be no external dependencies on the value?
    • Is it duplication to directly change private member variables that have public accessors in other places besides the accessor?
    • 请考虑以下代码:

      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;
        }
      }
      

      即使已更改变量永远不会公开(通过公共访问者或其他方式),同一行代码实际上重复四次: this.changed = true (三次)和 this.changed = false (一次)。同样, this.start this.end 的分配发生多次。相对于:

      Even though the changed variable is never exposed (through public acccessors or otherwise), the same line of code is essentially repeated four times: this.changed = true (thrice) and this.changed = false (once). Similarly, the assignment of this.start and this.end happens multiple times. As opposed to:

        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()。)

      The updated code is quite similar, but the duplication of all assignments is removed (presume dirty() and clean() use accessors). (There is a duplicated call to dirty() in the constructor that was not there before due to reusing the accessor methods for assignment.)

      问题不在于 this.changed = true 是否更容易理解为 dirty()

      The question is not about whether this.changed = true is more readily understood as dirty().

      问题在于是否 this.variable = value 是知识的一部分,因此应具有一致使用的单一,明确,权威的表示形式:对应的访问器。因此,一般情况为:

      The question is about whether this.variable = value is a "piece of knowledge" and should therefore have a "single, unambiguous, authoritative representation" that is used consistently: a corresponding accessor. Thus 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 );
        }
      }
      

      相比:

      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实现是否复制了知识?

      In C1, the variable v is directly assigned in multiple places. In C2, the variable v is is directly assigned in a single spot. Even though, in both cases, v is completely private, does the C1 implementation duplicate a "piece of knowledge"?

      推荐答案


      该语句与直接在多个地方的整个类中直接设置私有成员变量的值相符吗?

      How is that statement reconciled with directly setting a private member variable's value throughout a class in multiple places?

      有一个私有成员变量。因此,只有一个表示。更改此表示形式的语句本身不是表示形式。具有多个访问/更改表示形式的语句与具有多个表示形式不同。

      There is a single private member variable. Therefore there is a single representation. The statements that change this representation are not representations themselves. Having multiple statements that access / change the representation is not the same as having multiple representations.


      这很重要,因为没有外部依赖项

      Does it matter as there can be no external dependencies on the value?

      否。


      直接更改除访问者之外在其他地方具有公共访问者的私有成员变量是否重复?

      Is it duplication to directly change private member variables that have public accessors in other places besides the accessor?

      否。

      这不一定 意味着这样做是个好主意。

      That doesn't necessarily mean that it is a good idea to do it though.

      在您的示例中,选择是直接访问和更新脏标志,还是通过轻量级私有方法进行选择。 IMO,这归结为价值判断,即哪种方法可以使您的代码更具可读性。我的感觉是,至少在这种情况下,这两种方法之间几乎没有区别。在其他情况下,使用内部方法访问/更新永远不会公开的私有状态可能会更有力。

      In your example, the choice is between accessing and updating a "dirty" flag directly or doing this via light-weight private methods. IMO, this boils down to a value judgment as to which approach gives you more readable code. And my feeling is that there is little difference between the two approaches, at least in this case. In other cases, there could be a stronger case for using internal methods to access / update private state that is never exposed.

      如果需要将状态公开到外部那么最好在类中声明变量为私有,并为其他类提供getter和setter方法。而且,如果已经声明了这些getter和setter,则可以(较弱)说明类本身应该使用它们。

      If the state needs to be exposed outside of the class then there is a strong case for declaring the variables private and providing getters and setters for other classes to use. And if those getters and setters have been declared, then you can make a (weaker) case that the class itself should use them.

      对于那些关注Java的getter和setter的效率或其他方面,这很可能不会对性能产生任何影响。现代JVM中的JIT编译器几乎可以肯定内联方法,例如 clean() dirty() isDirty()产生机器指令的过程等同于直接获取和设置变量的情况。确实,最新的JIT编译器在推断出不需要分派的方法时,甚至会内联非最终的公共方法。

      For those people who are concerned about the efficiency or otherwise of getters and setters in Java, the chances are that it will make no difference to performance. The JIT compiler in a modern JVM will almost certainly inline methods like clean(), dirty() and isDirty() resulting in machine instructions are equivalent to the case where you get and set the variables directly. Indeed, the latest JIT compilers will even inline non-final public methods when they can deduce that the methods don't need to be dispatched.

      这篇关于变量值分配操作重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆