持有类实例的替代方案

时间:2014-04-27 11:53:01

标签: java

我有一个对象本质上是一个数据结构,其中的方法需要访问' Main' class(可以有这个类的多个实例)。我目前所做的是在构造函数中传递主类的实例,但这看起来有点笨拙。我也可以在方法调用中传递一个主类的实例,但这似乎增加了太多的复杂性,我很可能也会遇到同样的问题,因为它并不总是调用方法的主类。

我不是在寻找静态方法/变量,因为我正在对主类中的实例变量进行更改。

有没有更好的方法来实现这一点,而无需在多个地方存储实例?

示例代码:

public class Main {
    public Main() {
        Class1 class1 = new Class1(this);
        Class2 class2 = new Class2();

        class1.doSomething();
        class2.doSomething(this);
    }

    public void doSomethingElse() {
        // There is a point to this... I swear...
    }
}

public class Class1 {
    private Main instance;

    public Class1(Main instance) {
        this.instance = instance;
    }

    public void doSomething() {
        instance.doSomethingElse();
    }
}

public class Class2 {
    public void doSomething(Main instance) {
        instance.doSomethingElse();
    }
}

5 个答案:

答案 0 :(得分:1)

如果您担心内存使用或资源管理,请考虑即使您有50个数据存储类对象,您只需要1个Main类实例,并将此相同的实例发送给所有数据存储对象。然后,示例中的Class1.instance变量将指向与Main相同的Class49.instance实例。这就是指针的工作方式以及使它们变得更好的原因。

您可以使您的数据结构类扩展Main类,但除此之外(根据您的意愿排除静态),无法将实例作为参数发送给构造函数或方法。

答案 1 :(得分:1)

要判断什么是更好的,请始终查找代码的读者所期望的内容。

首先,有一个'有一个'关系。如果您说Class1始终对同一个Main实例感兴趣。并且在任何时候都有这种联系是有意义的(所以Class1始终可以合理地调用Main中的方法。然后Class1是更好的选择。

在其他情况下,您可以争论:Class2根据传递的Main实例提供服务。那么这是更好的选择。

在您的示例中,Class1Class2个实例都是短暂的。在这种情况下,我假设他们没有状态,我会去将Main的实例传递给函数。这在功能上等同于静态方法,但是,通过在无状态对象的实例上执行它,您可以保持选项打开以供将来扩展和测试。我的一个示例扩展是我后来添加了'设置'对于我的助手类(在您的示例中为Class2),这些设置在助手类的所有函数中都是活动的。

答案 2 :(得分:0)

也许单身模式或这种模式的扩展可能是你需要的?对象(来自Class1或Class2的实例)将访问Main.getInstance()以接收/ Main类的实例(可以扩展单例模式以便仅支持有限数量的实例而不仅仅支持一个实例)。

答案 3 :(得分:0)

如果您担心每次都必须传递Main类实例(以及稍后可能会在程序增长时传递其他实例)的维护开销,那么您可能正在寻找的是依赖注入框架(您目前正在做的是依赖注入;依赖注入框架旨在自动化该过程)。春天是最着名的,但也有其他。如果你期望项目变得很大(可能需要知道如何使用这样的框架,这是一个相当大的开销),这可能是值得的,但它将简化确保所有对象都引用他们所需的一切的任务。

答案 4 :(得分:0)

这取决于你的目标,但你可以使用内部类(非静态)。它有一个不可见的引用(Main.this),因此资源方面没有区别,但你不必明确地传入引用。

    public class Main {
        public Main() {
            Class1 class1 = new Class1();
            class1.doSomething();
        }

        public void doSomethingElse() {
        }

        public class Class1 {
            public void doSomething() {
                doSomethingElse();
            }
        }
    }