Effective Java-1.考虑使用静态工厂方法代替构造方法

静态工厂方法的优点

  • 不像构造方法,静态工厂是有名字的
    • 精心构造的名称使得静态工厂方法更容易使用和理解,即知道创建的是什么对象
  • 与构造方法不同,不用每次都创建一个新的对象
    • 可以使用不可变类预先构建实例
    • 可以在构造时缓存实例
    • 类似于享元模式,可以极大提供性能
    • 实例控制。对于实例的创建和使用有严格的控制
  • 可以返回类型的任何子类型,更具灵活性
    • 灵活:API可以返回它的对象但是并不公开它的类,隐藏了实现类
    • JDK大量使用,如Collection接口的伙伴类Collections
    • JDK8后可以在接口中使用静态方法
  • 返回对象的类可以根据输入参数的不同而不同
    • 例子:EnumSet类,底层可以枚举类型的大小返回不同类型的实例,优化性能。后期也可以方便对实例的类型进行淘汰或者更新,不会影响客户端代码
  • 在编写包含该方法的类时,返回的对象的类不需要存在
    • 服务提供框架的基础,JDK通用服务提供框架:java.util.ServiceLoader
      静态工厂方法的缺点:
  • 没有公共或受保护构造方法的类不能被子类化
    • 不过因祸得福,鼓励使用组合而非继承
  • 程序员很难找到它们
    • 提供一个静态工厂方法的常用名称
    • 方法名 说明 示例
      from 类型转换方法,它接受单个参数并返回此类型的相应实例 Date d = Date.from(instant)
      of 聚合方法,接收多个参数返回该类型实例,并把它们合并在一起 Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING)
      valueof fromto更为详细的替代方式 BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE)
      instance & getInstance 返回一个由其参数(如果有的话)描述的实例,但不能说它具有相同的值 StackWalker luke = StackWalker.getInstance(options)
      create & newInstence instancegetInstance有些类似,除了该方法保证每个调用返回一个新的实例 Object newArray = Array.newInstance(classObject, arrayLen)
      getType getInstance类似,但是如果在工厂方法中不同的类中使用。Type是工厂方法返回的对象类型 FileStore fs = Files.getFileStore(path)
      newType newInstance类似,但是如果在工厂方法中不同的类中使用。Type是工厂方法返回的对象类型 BufferedReader br = Files.newBufferedReader(path)
      type getTypenewType简洁的替代方式 List<Complaint> litany = Collections.list(legacyLitany)
posted @ 2022-12-13 14:10  WYia  阅读(33)  评论(0编辑  收藏  举报