【问题标题】:Appropriate way to pass instance of class to other classes (Java)将类实例传递给其他类的适当方法(Java)
【发布时间】:2014-04-25 12:44:58
【问题描述】:

我有一个主类,它有许多其他类中经常需要的与实例相关的方法,我经常发现自己在构造函数中传递了一个主类的实例。我经常发现这涉及到具有主类实例的类的多层深度,这些实例已经从一个实例复制到另一个实例,我无法想象这对内存使用有好处。

有没有一种方法可以做到这一点,而不必在构造函数或方法中传递实例,或者至少有一种方法可以减少主类实例使用的内存。

为了明确我不是在寻找静态方法,它被设计为能够拥有多个主类的实例。

示例代码:

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

    public void someMethod() {
        //Do something
    }
}

public class Class2 {
    private final Main instance;

    public Class2(Main instance) {
        this.instance = instance;
        Class3 class3 = new Class3(instance);
    }
}

public class Class3 {
    private final Main instance;

    public Class3(Main instance) {
        this.instance = instance;
        instance.someMethod();
    }
}

【问题讨论】:

  • 您意识到这些字段仅使用 32/64 位内存,因为它们只是对您的实例的引用,对吧?所以,这里实际上并没有“内存问题”。
  • 果汁?春天?依赖注入——解耦是关键!!如果有人告诉您将方法设为静态或做任何其他事情以使您的代码不符合 OOP,请帮自己一个忙,然后忽略它们。
  • @HovercraftFullOfEels 并不是说​​您在这个特定示例中错了,但这是普遍的真理吗?静态实用程序方法有问题吗?
  • @ElliottFrisch:不,你是对的,实用方法应该是静态的。但是在没有提到这些实用方法的情况下使用静态作为一个广泛的答案是错误的。
  • 类的名称“Main”强烈建议在应用程序中不需要有多个类的实例或其数据的副本。如果您不需要多个实例,则静态方法或单例是合适的解决方案。

标签: java instance


【解决方案1】:

您可以使用依赖注入设计模式。

Dependency-Injection-Design-Pattern

Spring、Google Guice 和 Java EE CDI 框架促进了 通过使用 Java Reflection API 进行依赖注入的过程和 java注解。我们只需要注释字段、构造函数或 setter 方法并在配置 xml 文件中配置它们或 类。

【讨论】:

  • 我发现带有配置文件的 Spring 依赖注入是一个比问题更糟糕的解决方案。通常,部署中所需的配置文件与测试中使用的配置文件不同,因为后者经常使用模拟或存根来避免必须在完整的部署风格环境中进行测试。结果是部署配置文件从来没有经过测试,导致运行出现问题。
  • @WarrenDew 我并不坚持 OP 只为此而使用 Spring Framework。OP 可以根据要求进行选择。
  • 你的引用暗示了使用配置文件,这会遇到我提到的问题。我同意在代码中而不是在单独的配置文件中使用带有配置的 Guice 可能不会遇到这个问题,但它也可能更难测试 - 而且你的答案没有提到配置中的替代方案代码,无论如何。
  • @WarrenDew 你可以在 Spring 中使用注解来配置代码而不是 xml 文件。
  • @WarrenDew 请阅读此“在配置 xml 文件或类中配置它们。”这是我的答案
【解决方案2】:

您还可以使用依赖注入将依赖的属性或对象传递给所需的类。 一种流行的框架是Google Guice.

【讨论】:

    【解决方案3】:

    您可以将 Main 类中的 someMethod() 之类的方法设为静态,或者如果这不可行,则将 Main 类本身设为单例。

    前一种方法的例子:

    public class Main {
        public Main() {
            Class2 class2 = new Class2(this);
        }
    
        public static void someMethod() {
            //Do something
        }
    }
    

    现在您不必再传递 Main 的实例了,因为其他类可以直接调用 Main.someMethod()

    【讨论】:

    • 嗯,无缘无故投反对票。我猜有些人实际上并不编写必须部署和工作的代码。
    • 据我了解,如果我在主类中创建了一个静态方法,那么它将无法返回实例,因为该方法属于类而不是对象。
    • 问题中没有迹象表明静态方法是解决问题的有效方法(“主”类可能有多个实例)。此外,我发现在非实用程序类中粗心地应用静态方法往往会导致代码脆弱且难以测试。
    • @user2248702 您可以将 Main 类中的方法设为静态,而不是 Main 类本身。我添加了一个代码示例来澄清。
    • @Aurand 也没有迹象表明静态方法不是有效的解决方案。这就是我提供两种解决方案的原因:一种适用于静态方法适用的情况,另一种适用于静态方法不适用的情况。但是,鉴于该类被称为“Main”,我强烈怀疑与大多数类不同,它的数据可能是全局适用的,因此静态函数可能是合适的。与使用静态方法和数据相比,过分努力避免使用静态方法和数据时遇到的麻烦要多得多,尽管我对这两者都不是粗心大意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多