几个班级之间的沟通

时间:2014-07-04 18:47:00

标签: java class design-patterns

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

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

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);
像这样,并花费几行代码来更新所有内容。从" main"创建引用的地方课程,其中"主要"不一定是具有main方法的类,而是具有最多动作的类。

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

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

3 个答案:

答案 0 :(得分:3)

处理此问题的标准方法是所谓的observer pattern

您应该确保只有一个Gamma实例,否则您必须确保所有实例都是同步的。

ab要求g注册为观察员。 g通知所有观察者其状态发生变化。

class Gamma extends Observable {
    int x = 10;

    public int getX(){
        return x;
    }
    public void setX(int y){
        x = y;
        notifyObservers (null);
    }
}

class Alpha implements Observer {
    // ...

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

    public void update(Observable o, Object arg) {
       // this method gets called by g whenever g's state changes
       // do necessary updates here
       // ...
    }
 }

答案 1 :(得分:3)

使用MVC(模型 - 视图 - 控制)模式或其变体之一,并且具有需要保持相同数据共享模型的类。例如,也许Gamma是你的模型,然后让其他类共享相同的Gamma实例

如,

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

要让类通知另一个类的状态更改,然后使用,请使用JohnB建议的观察者模式。


请注意,获得观察者支持的一种方法是使用JavaBean的PropertyChangeSupport。例如:

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

注意:使用共享Gamma类注入A和B类可能是最好和最干净的方法是通过依赖注入,例如可以从Spring的一个模块或Guice框架获得。

答案 2 :(得分:0)

如果你真的想这样做......使用JohnB提到的观察者模式。

但是,我并不完全同意你的理由。 跨类拆分代码不是使用观察者模式的好理由。应该有比这更好/更多功能的要求。当然我不知道确切的要求所以我不能概括。

我建议采用一种截然不同的方法。从添加一点功能的基类开始,然后逐层扩展以添加更多功能。

这将让您拥有精美清晰的代码,这些代码具有可读性和可维护性,同时还能保持您的对象模型代表功能。