2010-12-12 13 views
7

¿Cuál es la mejor forma de compartir datos entre clases separadas en Java? Tengo un conjunto de variables que son usadas por diferentes clases en archivos separados de diferentes maneras. Voy a tratar de ilustrar una versión simplificada de mi problema:Cómo compartir datos entre clases separadas en Java

Esta fue mi código antes:

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

Ahora se ve algo como esto:

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

Así que de todos modos, debería pasar xey cada vez (donde x, y son variables almacenadas en el func de la clase auxiliar)?

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

Mi idea era tener una clase de contenedor especial donde se mantienen xy y. La clase de nivel superior tendría una instancia de la clase contenedora y cambiaría x, y utilizando los métodos establecidos.

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

Mis clases de ayuda también tendrían una instancia del contenedor y que apuntarían a la misma instancia que en el nivel superior. De esta forma, acceden a la misma x, y que en el nivel superior.

me gustaría saber si debo

  • Utilice la clase de contenedor de carga
  • x, y cada vez en las subclases
  • ?? ¿Algún método mejor?
+3

La respuesta aquí es, lamentablemente, 'depende'. programadores.se podría ser un objetivo más fértil para esta pregunta. – bmargulies

+0

Si la clase interna no es estática, puede acceder a los miembros de la clase principal también ... – Vojta

+0

No es una clase interna si está en un archivo diferente. Y no es una subclase si no extiende la superclase. – Armand

Respuesta

10

Supongo que la respuesta a su pregunta es el patrón de diseño llamado Singleton. Básicamente, le permite obtener y explotar la misma instancia (y única) de una clase cuando lo desee en su sistema.

Esta es su aplicación (por favor, perdona posibles errores de sintaxis, que no compilarlo):

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

entonces, si en su código en otro lugar de importar el contenedor se puede escribir por ejemplo

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

y usted afectará los atributos de la instancia única de contenedor que tiene en su sistema

En muchos casos, sin embargo, es mejor utilizar Dependency Injec patrón de resolución, ya que reduce el acoplamiento entre los diferentes componentes.

+0

Muy interesante. Tiene una variable estática de sí misma. Solo me pregunto, ¿cómo sale esto del alcance? Si es estático, ¿no seguirá existiendo? ¿O lo configuro como nulo cuando termino con eso? – f20k

+0

Lo siento pero supongo que no he entendido tu pregunta :(de todos modos, como su instancia es estática, una vez inicializada, seguirá existiendo. No tienes que, y no podrías, establecerla como nula. Considéralo un repositorio compartido de sus variables :) Sin embargo, aquí hay una explicación del patrón http: //en.wikipedia.org/wiki/Singleton_pattern – Sindico

+0

Hmm, el singleton tendrá sentido si solo necesito instanciarlo una vez. Sin embargo, mi función de nivel superior es en realidad un hilo que se instanciará/destruirá varias veces durante la ejecución del programa. Bueno, supongo que puedo sobrescribir los valores cada vez. – f20k

0

Estoy teniendo dificultades para ver cuál es tu problema, ¿por qué no quieres pasar x an como parámetro?

Oh, bueno. Suponiendo que no lo haga, no veo la necesidad de una nueva clase de contenedor. Hacerlo de esta manera:

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()** 
    } 
} 

Por supuesto, es necesario agregar el métodos de acceso público getX() y getY() para Top_Level_Class.

Si no desea que SubClass1a dependa de Top_Level_Class, puede crear una interfaz que proporcione acceso a las variables.

+0

Hmm está bien. Tendré que echar un vistazo a las interfaces más. La razón principal por la que no quería aprobar x, y cada vez es porque tengo varias funciones en varias SubClasses que cada una usa (x, y, z, etc.) y no parece correcto pasarlas como 6-8 variables cada una tiempo que llamo una función. Las subclases solían ser dependientes, pero estoy tratando de sacarlas del archivo para que puedan ser utilizadas en un proyecto diferente. – f20k

+1

@ f20k Su instinto de no querer pasar de 6 a 8 parámetros a un método está en el camino correcto. Las listas de parámetros que duran tanto insinúan que debería considerar agrupar esos parámetros en un objeto o 2. – dhable

+0

@Dan, gracias por su sugerencia. Creo que implementaré un contenedor. Tiene mucho sentido. Solo me preocupaba que sería una mala práctica de programación si compartía los datos de esta manera. – f20k

0

cita en bloque La razón principal por la que no quería pasar x, y cada vez es porque tengo varias funciones en varias subclases que cada uso (x, y, z, etc.) y que no parecía derecho a pasar como 6-8 variables cada vez que llamo a una función. Las subclases solían ser dependientes, pero estoy tratando de sacarlas del archivo para que puedan ser utilizadas en un proyecto diferente. Blockquote

Si este es el caso, entonces es mejor que abstraigas tus variables a una clase contenedora. Si cada instancia de estas clases que ya no son dependientes va a usar un gran subconjunto de estas variables, entonces tiene sentido tenerlas todas en una instancia. Las variables que están lógicamente relacionadas se deben encontrar en el mismo lugar.Su enfoque debe ser algo como:

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 
} 

Esto le impide entrar en un paso variable de situación de los espaguetis de código, y cuando se quiere utilizar sólo uno o dos de estas clases más tarde su código es modular suficiente para el puerto con solo esas clases y tu contenedor.

+0

Esta sintaxis es incorrecta, y parece más complicada que la sugerencia original. – Armand

0

Esta pregunta es un poco loca: el código en la pregunta no se compilará.

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 
} 

Tendrá que definir y ADoerBDoer también.

+0

Lo siento, el código que escribí allí es para ayudar a dar una idea de lo que quiero hacer. Realmente no funciona. El código real es realmente bastante complicado con más de 100 líneas. Básicamente estoy tratando de compartir algunas variables muy usadas en top_level_class entre las clases de ayuda en archivos separados. La pregunta es qué método sería el mejor: eficiente y prudente – f20k

Cuestiones relacionadas