何时使用getInstanceOf而不是构造函数

时间:2010-02-03 21:30:48

标签: java constructor software-design

几个月前,我参加了由两位独立软件开发公司代表主持的演讲。它主要是关于良好的软件设计和实践。

这两个人主要谈论Java,我记得他们说,在某些情况下,使用getInstanceOf()而不是构造函数是一个很好的做法。它与总是从不同的类而不是构造函数调用getInstanceOf()有关,以及如何在更大规模的项目中采用更好的方法。

正如你所看到的,我现在记不起来了:/但我记得他们使用的论据真的很有说服力。我想知道你们有没有遇到过这样的设计,你知道它什么时候有用吗?或者你认为它根本不存在?

4 个答案:

答案 0 :(得分:10)

答案 1 :(得分:7)

他们可能正在谈论静态工厂方法模式(而不是用于动态创建对象的反射API方法)。

在构造函数中使用getInstanceOf()等方法并使用new有几个优点。静态工厂方法可以......

  1. 如果在某些情况下需要(基于环境条件,例如属性和其他对象/单例或方法参数),则选择创建主类的不同子类。

    < / LI>
  2. 选择返回现有对象而不是创建对象。有关此示例,请参阅Java API中的Boolean.valueOf(boolean)

  3. 执行与构造函数相同的操作 - 只返回类本身的新实例。

  4. 提供许多不同类型的方法来构造一个新对象并命名这些方法,以便它们不那么混乱(例如,尝试使用构造函数,很快就会有许多不同的重载)。有时,如果您需要能够以两种不同的方式创建实例但只需要相同类型的参数,那么构建器甚至无法实现这一点。例如:

    // This class will not compile!
    public class MyClass {
        public MyClass(String name, int max) {
            //init here
        }
        public MyClass(String name, int age) {
            // init here
        }
    }
    
    // This class will compile.
    public class MyClass2 {
        private MyClass2() {
        }
        public static MyClass2 getInstanceOfMax(String name, int max) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
        public static MyClass2 getInstanceOfAge(String name, int age) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
    }
    
  5. 上述任何组合。

  6. 最重要的是,它隐藏了从其他类实例化实例的细节,因此将来可以改变(构造封装)。

  7. 构造函数只能创建所请求的确切类型的对象的新实例。它以后不能改变。

    这种模式的一些缺点是:

    1. 工厂方法是静态的,因此不能在子类中继承;子类很容易访问父构造函数。

    2. 工厂方法名称可能有很大差异,这可能会让一些(新)开发人员感到困惑。

    3. 您还要求个人经历。是的,我经常使用这两种模式。对于大多数类构造函数,但是当有更多高级需求时,我使用静态工厂。我还从事其他语言的项目(专有,但类似于Java),这种形式的构造是强制性的。

答案 2 :(得分:1)

我怀疑你的意思是Class类的newInstance method。您可以这样调用它:MyClass foo = MyClass.newInstance();

这种形式的对象实例化在creational patterns中很流行;当您想要指定对象外部的具体运行时类型时,它非常有用,例如在属性或XML文件中。

答案 3 :(得分:1)

如果Drew是正确的,newInstance()是Java Reflection API的一部分。所以它不像使用构造函数那么自然。

为什么建议在大型项目中使用它可能会导致Java Bean programming style导致对象的创建特别明显。在大型项目中,创建对象不应该是一个贯穿各领域的问题,而应该是一个明确的责任,通常来自一个来源/工厂。但恕我直言,你可以通过IoC pattern获得所有这些优势以及更多优势。