几个班级之间的沟通

Fox*_*der 5 java design-patterns class

每当我制作一个程序时,我倾向于在不同的文件中划分不同的部分,我认为它看起来更整洁.为了使问题更具体,我说这个虚拟代码由四个类组成,

public class dummy {
    public static void main(String[] args){
        Alpha a = new Alpha();
        Beta b = new Beta();
        Gamma g = new Gamma();

        int x,y,z,j,k,l,o,p,q;

        x = a.getGammaX();
        y = b.getGammaX();
        z = g.getX();

        a.setGammaX(1);

        j = a.getGammaX();
        k = b.getGammaX();
        l = g.getX();

        b.setGammaX(2);

        o = a.getGammaX();
        p = b.getGammaX();
        q = g.getX();
        }
    }

class Alpha{
    Gamma g = new Gamma();
    public int getGammaX(){
        return g.getX();
    }

    public void setGammaX(int x){
         g.setX(x);
    }
}

class Beta{
    Gamma g = new Gamma();
    public int getGammaX(){
        return g.getX();
    }

    public void setGammaX(int x){
        g.setX(x);
    }
}

class Gamma{
    int x = 10;

    public int getX(){
        return x;
    }
    public void setX(int y){
        x = y;
    }
}
Run Code Online (Sandbox Code Playgroud)

Alpha和Beta类与Gamma通信.整数的目的是打印出它们的值,并在从不同的类调用setter之后将它们相互比较.我分割部分时遇到的一个普遍问题是,当一个类改变Gamma中的值时,其他类具有过时值,当setter方法具有时,x,y,z变量仍将具有Gamma中的旧值x被叫,除非我在花了很长时间才找到它之前发现了这个.

我倾向于通过传递Gamma类的一个引用来绕过这个,

Gamma g = new Gamma();
Alpha a = new Alpha(g);
Beta b = new Beta(g);
Run Code Online (Sandbox Code Playgroud)

像这样,并花几行代码来更新所有内容.从"main"类创建引用的位置,其中"main"不一定是具有main方法的类,而是具有最多动作的类.

我的问题是,是否有一种处理这类问题的标准方法,其中多个类与另一个类进行通信,更改值等,最终得到过时的值?

我的问题往往比显示的更微妙,但实质上这是我倾向于花一些时间来尝试修复.我很抱歉,如果解释很混乱,我很难把问题弄清楚,如果太难以理解,请在评论中写一下,我会尽量清楚一点.

Hov*_*els 3

Use the MVC (model-view-control) pattern or one of its variants, and have classes that need to hold the same data share a model. For instance perhaps Gamma is your model, then have the other classes share the same Gamma instance.

e.g.,

public class Dummy {
   public static void main(String[] args) {
      Gamma g = new Gamma();

      Alpha a = new Alpha(g);
      Beta b = new Beta(g);

      // .........


   }
}

class Alpha {
   private Gamma g;

   public Alpha(Gamma g) {
      this.g = g;
   }

   public int getGammaX() {
      return g.getX();
   }

   public void setGammaX(int x) {
      g.setX(x);
   }
}

class Beta {
   // Gamma g = new Gamma();
   private Gamma g;

   public Beta(Gamma g) {
      this.g = g;
   }

   public int getGammaX() {
      return g.getX();
   }

   public void setGammaX(int x) {
      g.setX(x);
   }
}

class Gamma {
   int x = 10;

   public int getX() {
      return x;
   }

   public void setX(int y) {
      x = y;
   }
}
Run Code Online (Sandbox Code Playgroud)

To have have classes notified of state changes on another class, then use, use an observer pattern as recommended by JohnB.


Note that one way to gain observer support is to use JavaBean's PropertyChangeSupport. For example:

class Gamma {
   public static final String X = "x";
   private PropertyChangeSupport support = new PropertyChangeSupport(this);

   private int x = 10;

   public int getX() {
      return x;
   }

   public void setX(int x) {
      int oldValue = x;
      int newValue = this.x;
      this.x = x;
      support.firePropertyChange(X, oldValue, newValue);
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      support.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      support.removePropertyChangeListener(listener);
   }
}
Run Code Online (Sandbox Code Playgroud)

Note: probably the nicest and cleanest way to inject the A and B classes with a shared Gamma class is via dependency injection such as available from one of Spring's modules or from the Guice framework.