2010-12-12 214 views
7

在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是存储在helper类func中的变量)?

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

我的想法是有一个特殊的容器类,其中x和y是举行。顶级类将拥有容器类的实例,并使用set方法更改x,y。

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

我的帮助类也有一个容器的实例,它将指向与顶层相同的实例。这样他们访问与顶层相同的x,y。

我想知道我是否应该

  • 使用容器类,Y每次
  • 负载x转换成子类
  • ?一些更好的方法?
+3

可悲的是,这里的答案是'它取决于'。程序员.se可能是这个问题更加肥沃的目标。 – bmargulies 2010-12-12 00:49:56

+0

如果内部类不是静态的,那么它也可以访问父类成员... – Vojta 2010-12-12 00:50:49

+0

如果它在不同的文件中,它不是内部类。如果它不扩展超类,它就不是子类。 – Armand 2010-12-12 03:25:39

回答

10

我想你的问题的答案是称为Singleton的设计模式。 它基本上允许您在系统中随时获取并利用相同(和唯一)的类实例。

这是它的实现(请原谅可能的语法错误,我没有编译):

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; 

,并且您将影响您的系统中的唯一容器实例的属性

在许多情况下,最好使用依赖关系注入器因为它减少了不同组件之间的耦合。

+0

非常有趣。它本身有一个静态变量。只是想知道,这件事情如何超出范围?如果它是静态的,它不会存在吗?或者当我完成它时将它设置为空? – f20k 2010-12-14 21:47:01

+0

对不起,但我想我还没有理解你的问题:(无论如何,因为它的实例是静态的,一旦初始化,它将保持存在。你不必,也不能将它设置为null。你的变量:)然而,这是对模式http://en.wikipedia的解释。org/wiki/Singleton_pattern – Sindico 2010-12-14 22:06:34

+0

嗯,如果我只需要实例化一次,Singleton就会有意义。但是,我的顶级函数实际上是一个在整个程序执行过程中会多次实例化/销毁的线程。那么我想我可以每次都重写这些值。 – f20k 2010-12-16 18:23:42

0

我很难看出你的问题是什么 - 为什么你不想传递x和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。

如果您不希望SubClass1a依赖于Top_Level_Class,那么您可以创建一个接口来提供对变量的访问。

+0

嗯没关系。我将不得不更多地看看接口。我不想每次传递x,y的主要原因是因为我在几个子类中都有几个函数,每个函数都使用(x,y,z等),并且它看起来似乎并不正确,每个子类都有6-8个变量我称之为功能。子类过去是依赖的,但我试图将它们从文件中取出,以便它们可以在不同的项目中使用。 – f20k 2010-12-12 01:05:25

+1

@ f20k你不想将6-8个参数传递给方法的直觉就在正确的轨道上。参数列表通常意味着您应该考虑将这些参数捆绑到一个对象或2. – dhable 2010-12-12 06:35:27

+0

@丹,感谢您的建议。我想我会实施一个容器。这很有道理。我只是担心如果我以这种方式分享数据,这将是不好的编程实践。 – f20k 2010-12-12 16:35:57

0

块引用 主要的原因我并不想通过X,Y每次都是因为我有几个子类了几个函数,每次使用(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 
} 

这样可以使你进入一个变量传递意大利面条代码的情况下,当你想使用一个或两个这些类的后来你的代码是模块化的,足以端口只是这些类和你的容器。

+0

此语法错误,似乎比原始建议更复杂。 – Armand 2010-12-12 03:26:59

0

这个问题有点疯狂 - 问题中的代码不会编译。

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 
} 

您还需要定义ADoerBDoer

+0

对不起,我写在那里的代码有助于了解我想要做什么。它并没有真正的工作。实际的代码实际上相当复杂,有100多行。我基本上是试图在不同文件中的助手类之间共享top_level_class中一些非常常用的变量。问题是哪种方法最好 - 高效且明智地选择 – f20k 2010-12-12 04:50:24