3

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

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

正如你所看到的,我现在记不太清了:/但我记得他们使用的论点非常有说服力。我想知道你们中是否有人遇到过这样的设计,你会说它什么时候有用?还是你认为根本不是?

4

4 回答 4

10

考虑静态工厂方法而不是构造函数——<em>Joshua Bloch

于 2010-02-04T01:15:34.643 回答
8

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

方法有几个优点,例如相getInstanceOf()对于构造函数和使用new. 静态工厂方法可以...

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

  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. 而且,最重要的是,它隐藏了从其他类中实例化实例的细节,因此将来可以改变(构造封装)。

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

这种模式的一些缺点是:

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

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

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

于 2010-02-04T04:36:32.510 回答
1

我怀疑你的意思是 Class 类的newInstance方法。你会像这样调用它: MyClass foo = MyClass.newInstance();

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

于 2010-02-03T21:37:52.247 回答
1

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

为什么建议在大型项目中使用它可能是因为它导致了Java Bean 编程风格,并且清楚地使对象的创建变得特别。在大型项目中,创建对象不应该是一个横切关注点,而是一个明确确定的责任,通常来自一个来源/工厂。但是恕我直言,您可以通过IoC 模式获得所有这些优势以及更多优势。

于 2010-02-03T22:09:31.253 回答