重构:用静态工厂方法代替构造方法

对于类而言,为了让客户端获取它自身的一个实例,最传统的方法就是提供构造方法。除此之外,我们今天将介绍的静态工厂方法也是被用得很广泛的一种方式。比如Boolean源码中将boolean基本类型值转换成一个Boolean对象引用:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

如果不通过公有的构造方法,或者说除了公有的构造方法之外,类还可以给它的客户端提供静态工厂方法。提供静态工厂方法而不是公有的构造方法,这样做既有优势,也有劣势。

1. 优势

(1)第一大优势在于,静态工厂方法是有名称的。如果构造方法的参数本身没有确切地描述正在创建的对象,那么具有适当名称的静态工厂会更容易使用,产生的客户端代码也更易于阅读。

(2)第二大优势在于,不必在每次调用它们的时候都创建一个新的对象。这使得不可变类可以使用预先创建好的对象,或者将构建好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象。上诉Boolean.valueOf(boolean b)方法就是如此,它从来不创建对象,而是返回缓存中的对象。

(3)第三大优势在于,它们可以返回原返回类型的任何子类对象。比如Arrays.asList()方法返回的就是List接口的一个子类对象。

2. 劣势

(1)第一大劣势在于,程序员很难发现它们。在API文档中,它们没有像构造方法那样在API文档中明确标识出来,因此,对于提供了静态工厂方法而不是构造方法的类来说,要想查明如何实例化一个对象是非常困难的。这一点需要我们通过在类或者接口注释中关注静态工厂,并遵守标准的命名习惯来弥补这一劣势。下面是静态工厂方法的一些惯用名称:

  • from:类型转换方法,它只有单个参数,返回该类型的一个对象。比如:Date date = Date.from(instant)
  • of:聚合方法,带有多个参数,返回该类型的一个对象,把它们合并起来。比如:Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING)
  • valueOf:比如:BigDecimal.valueOf(long val)
  • instance或者getInstance:大部分见于单例类。
  • create或者newInstance:和instancegetInstance一样,但create或者newInstance能够确保每次调用都返回一个新的实例对象。
  • get<Type>:像getInstance一样,但是在工厂方法处于不同的类中的时候使用。比如:FileStore fs = Files.getFileStore(path)
  • new<Type>:像newInstance一样,但是在工厂方法处于不同的类中的时候使用。比如:BufferedReader br = Files.newBufferedReader(path)
  • typeget<Type>newType的简版,比如:List<Complaint> litany = Collections.list(legacyLitany)
——End——
更多精彩分享,可扫码关注微信公众号哦。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值