Как обмениваться данными между отдельными классами в Java

каков наилучший способ обмена данными между отдельными классами в Java? У меня есть куча переменных, которые используются разными классами в разных файлах по-разному. Позвольте мне попытаться проиллюстрировать упрощенную версию моей проблемы:

Это был мой код до:

public class Top_Level_Class(){
    int x, y;

    // gets user input which changes x, y;
    public void main(){
       int p, q, r, s;
       // compute p, q, r, s
       doA(p,q,r);
       doB(q,r,s);
    }

    public void doA(int p, int q, int r){
       // do something that requires x,y and p, q, r
    }

    public void doB(int q, int r, int s){
       // does something else that requires x, y and q, r, s
    }
}

теперь это выглядит примерно так:

public class Top_Level_Class(){
    int x, y;
    SomeClass1a a = new SomeClass1a();
    SomeClass1a b = new SomeClass1b();
    // gets user input which changes x, y;
    public void main(){
       int p, q, r, s;
       // compute p, q, r, s
       a.doA(p,q,r);
       b.doB(q,r,s);
    }

public class SomeClass1a() {  // in its own separate file
    public void doA(int p, int q, int r){
       // do something that requires x,y and p, q, r
    }
}


public class SomeClass1b() {  // in its own separate file
    public void doB(int q, int r, int s){
       // does something else that requires x, y and q, r, s
    }
}

так или иначе, я должен передавать x и y каждый раз (где x, y-переменные, хранящиеся в вспомогательном классе func) ?

 a.set(x,y);
 a.doA(p,q,r);

моя идея состояла в том, чтобы иметь специальный класс контейнера, где X и y проводятся. Класс верхнего уровня будет иметь экземпляр класса контейнера и изменять x,y с помощью методов set.

// in the top level class:
Container c = new Container(x,y);
a.setContainer(c);
b.setContainer(c);

мои вспомогательные классы также будут иметь экземпляр контейнера, и он будет указывать на тот же экземпляр, что и на верхнем уровне. Таким образом,они получают доступ к тем же x, y, что и на верхнем уровне.

Я хотел бы знать, должен ли я

  • использовать класс контейнера
  • загрузить x, y каждый раз в подклассы
  • ?? Какой-нибудь лучший способ ??

4 ответов


Я думаю, ответ на ваш вопрос-это шаблон проектирования Синглтон. Это в основном позволяет вам получать и использовать один и тот же (и уникальный) экземпляр класса, когда вы хотите в своей системе.

это его реализация (простите возможные синтаксические ошибки, я не компилировал его):

class Container{

  //eventually provides setters and getters
  public float x;
  public float y;
  //------------

  private static Container instance = null;
  private void Container(){

  }
  public static Container getInstance(){
    if(instance==null){
       instance = new Container();
      }
      return instance;
  }
}

затем, если в другом месте кода вы импортируете контейнер, вы можете написать, например

Container.getInstance().x = 3;
temp = Container.getInstance().x;

и вы повлияете на атрибуты уникального экземпляр контейнера, который у вас есть в вашей системе

во многих случаях, однако, лучше использовать шаблон инъекции зависимостей, поскольку он уменьшает связь между различными компонентами.


Мне трудно понять, в чем ваша проблема-почему вы не хотите передавать x an y в качестве параметра?

о, хорошо. Предполагая, что вы этого не сделаете, я не вижу необходимости в новом классе контейнеров. Сделайте это так:

public class SubClass1a() {  // in its own separate file
    public void doA(Top_Level_Class caller, int p, int q, int r){
       // do something that requires x,y and p, q, r
       // **to get x use the expression term caller.getX() and caller.getY()**
    }
}

конечно, вам нужно добавить общедоступные методы getter getX() и getY () в Top_Level_Class.

Если вы не хотите, чтобы Подкласс1a зависел от Top_Level_Class, вы можете создать интерфейс, который предоставляет доступ к переменная.


Blockquote Главная причина, почему я не хочу проходить X и y каждый раз, потому что у меня есть несколько функций в несколько подклассов, что (Х,У, Z и т. д.), И это не кажется правильным, чтобы пройти в как 6-8 переменных каждый раз, когда я вызываю функцию. Подклассы раньше были зависимыми, но я пытаюсь вытащить их из файла, чтобы их можно было использовать в другом проекте. Blockquote

Если это так, то вам лучше абстрагировать свои переменные в контейнерный класс. Если каждый экземпляр этих более не зависимых классов будет использовать большое подмножество этих переменных, то имеет смысл иметь их все в одном экземпляре. Переменные, которые логически связаны, должны быть найдены в том же месте. Ваш подход должен быть примерно таким:

public class Top_Level_Class(){
Container container = new Container(x, y, p, q, r, s);
SubClass1a a = new SubClass1a(container);
SubClass1a b = new SubClass1b(container);
// gets user input which changes x, y using container's getters and setters
public void main(){
   // compute and set p, q, r, s
   a.doA();
   b.doB();
}

public class SubClass1a(Container c) {  // in its own separate file
    public void doA(c.getX, c.getY, c.getP, c.getQ, c.getR){
       // do something that requires x, y, p, q, and r
    }
}

public class SubClass1b(Container c) {  // in its own separate file

    public void doB(c.getX, c.getY, c.getQ, c.getR, c.getS){
       // does something else that requires x, y, q, r, and s
    }
}

public class Container(x, y, p, q, r, s) {
    //getters and setters for all variables
}

это удерживает вас от попадания в переменную, передающую ситуацию спагетти-кода, и когда вы хотите использовать только один или два из этих классов позже, ваш код достаточно модульный для порта только с этими классами и контейнером.


этот вопрос немного сумасшедший-код в вопросе не будет компилироваться.

public class Main {
    public static void main(String... args) {
        MutableDataContainer m = new MutableDataContainer();
        ImmutableDataContainer i = computeImmutableData();
        new ADoer().doA(m, i);
        new BDoer().doB(m, i);
    }
    ...
}

class MutableDataContainer {
    private int x, y;
    ... // getters and setters below
}

class ImmutableDataContainer {
    private final int p, q, r, s;
    ... // getters below
}

вам нужно определить ADoer и BDoer Как хорошо.