Effective Java学习笔记之第1条 考虑用静态工厂方法代替构造器

  第1条 考虑用静态工厂方法代替构造器

   对于类而言,为了让客户端获取自身都一个实例,最常用的方法是提供一个公有地构造器。还有一个方法:提供一个公有的静态工厂方法(static factory method)。

  示例1: 将boolean基本类型值转换成一个Boolean对象引用。

  public static Boolean valueOf(boolean b) {

    return b ? Boolean.TRUE : Boolean.FALSE;

  }

  静态工厂方法都优势:

  一。 静态方法都有名称。例如:构造器BigInteger(int, int, Random)返回的BigInteger可能为素数,如果用名为BigInteger.protablePrime的静态工厂方法来表示,显然更为清楚。

    当一个类需要多个带有相同签名的构造器时,就用静态工厂方法代替构造器,并且慎重的选择名称以便突出它们之间都区别。

  二。 不必在每次调用它们都是很都创建一个新的对象。这使得不可变对象可以使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用。Boolean.valueOf(boolean)方法说明了这项技术。这种方法类似于Flyweight模式。

    如果程序经常请求创建相同的对象,并且创建对象都带价很高,则这项技术可以极大的提升性能。

  三。静态工厂方法可以返回原返回类型都任何子类型都对象。 这种灵活性的一种应用是,API可以返回对象,同时又不会使对象都类变成公有的。这项技术适用于基于接口的框架(interface-based framework), 因为在这种框架中,接口为静态工厂方法提供了自然返回类型。接口不能有静态方法,因此按照惯例,接口Type的静态工厂方法被放在一个名为Types的不可实例化都类中。

    例如: Java Collections Framework的集合接口有32个便利实现,分别提供了不可修改的集合,同步集合等等。几乎所有这些实现都通过静态工厂方法在一个不可实例化都类(java.util.Collections)中导出,所有返回对象都的类都是非公有的。

    使用这种静态工厂方法时,甚至要求客户端通过接口来引用被返回的对象,而不是通过它的实现类拉引用被返回的对象,这是一种良好的习惯。

  四。在创建参数化类型实例都时候,它们使代码变得更加简洁。但通常要求连续两次提供类型参数。

    Map<String, List<String>> m = new HashMap<String, List<String>>();

    但是有了静态工厂方法,编译器可以替你找到类型参数,这被称作类型推导(type inference). 例如,假设HashMap提供了这个静态工厂方法:

    public static <K, V> HashMap<K, V> newInstance() {

      return new HashMap<K, V>();

    }

    你就可以用下面这句简洁地代码代替上面都声明:

    Map<String, List<String>> m = HashMap.newInstance();

  静态工厂方法都主要缺点:

    一。类如果不含公有的或者受保护的构造器,就不能被子类化。这样也会因祸得福,因为它鼓励复合,而不是继承。

    二。它与其它静态方法实际上没有任何区别。

  下面是静态工厂方法都一下惯用名称:

    valueOf --该方法返回的实例与它的参数具有相同的值。这样的静态工厂方法实际上就是类型转换方法。

    of -- valueOf的一种更为简洁地替代。

    getInstance -- 返回的实例是通过方法都参数来描述得,但不能说与参数具有相同的值。对于Singleton来说,该方法没有参数,并返回唯一的实例。

    newInstace -- 想getInstance一样,但newInstance能够确保返回的每个实例都与所有其他实例不同。

    getType -- 想getInstance一样, 但是在工厂方法处于不同的类中使用。Type表示工厂方法所返回的对象类型。

    newType -- 像newInstance一样,但是在工厂方法处于不同的类中使用。Type表示工厂方法所返回的对象类型。

  简而言之,静态工厂方法和公有构造器都各有用处,我们需要理解他们各自都长处。静态工厂通常更加合适,因此切忌第一反应就是提供公有的构造器,而不先考虑静态工厂。

posted @ 2013-10-27 21:05  yanjf  阅读(419)  评论(0编辑  收藏  举报