Effective Java 第一条:考虑用静态工厂方法替代构造器

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


  对于类而言,为了让客户端获得它自身的一个实例,最常用的方法就是提供一个 公有 的构造器,除了这种方式外,另外一种实现方式 是为类提供一个公有的的静态工厂方法

静态工厂方法的优势

公有构造器的方式的缺点

  • 只能通过new className() 的方式来实现
  • 每次调用必然返回一个新的对象
  • 返回类型就是该类

使用静态工厂方法的优势

  • 静态工厂方法是有名称的
    它可以描述返回对象的特点,一个类如果需要多个带有相同前面的构造器时,就用静态工厂方法来代替构造器,使用不同的方法名称以突出他们的区别比如 BigInteger.probalePrime() 这个静态工厂方法描述了返回的实例对象是一个素数。
  • 不必在每次调用它们的时候都创建一个新的对象
    对于一些创建代价比较大又可以重复利用的对象,我们可以预先创建好对象实例,或者将构建好的实例缓存起来,重复利用,每次调用工厂方法时返回相同的对象。
  • 可以返回原返回类型的任何子类型
    考虑到一些私有的类我们不想对外界暴露,又要提供获得该类对象的方法,采用静态工厂方法的方式可以让用户致电,被返回的对象是由相关接口精确确定的,对于返回对象的具体确定的类的存在对于客户端来说是不可见的。
    静态工厂方法返回的对象所属的类,在编写保护该静态工厂方法的类时可以不必存在。
    这种灵活的静态工厂方法构成了服务提供者框架(Service Provider Framwork)的基础,例如 JDBC(Java数据库连接) API,服务提供者框架是指这样一个系统;多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。
  • 在创建参数化类型实例的时候,它们使代码变得更加简洁
    在调用参数化类的构造器时,即使类型参数很明显,也必须指明,这通常要求你接连两次提供类型参数
    Map<String,List<String>> m = new HashMap<String,List<String>>,这个代码太冗长,使用静态工厂方法,编译器就可以替你找到类型参数。
public static <k,v> HashMap<k,v> newInstance(){
    return new HashMap<k,v>();
}
用下面这句代码替代之前繁琐的申明
Map<String,List<String>> m = HashMap.newInstance();
在我用Android Studio 的时候,Java 1.7 的时候,已经不需要申明两次泛型类型了,可以直接这样
Map<String,List<String>> m = new HashMap<>
所以这点上,你可以用这种方式只是拥有之前说的第二种优势

总结

  静态工厂方法和公有构造器都各有用处,我们需要理解它们各自的长处。静态工厂通常更有用处,优先考虑静态工厂方法。

静态工厂方法的缺点

  • 静态工厂方法的主要缺点在于,类如果不含有公有的或者受保护的构造器,就不能被子类化
    不过这也鼓励你使用复合(composition)来扩展类,而不是继承
  • 与其他静态方法实际上没有区别
    你无法向构造器那样在API文档中明确的标示出来这份方法是为了创建类实例的,不过你可以在类或者接口注释中关注静态工厂,并遵守标准的命名习惯,这可以弥补这一劣势

静态工厂方法的一些惯用名称

  • value of 实际上是类型转换方法
  • of valueof的一种简洁提地啊
  • getInstance 返回的实例是通过方法的参数来描述的
  • newInstanc new字样,你需要保证额每个实例都与所有其他实例不同,即每次都是创建一个实例,保证没有复用
  • getTypegetInstance 一样,但是在工厂方法处于不同的类中的时候使用。Type 表示工厂方法返回的对象类型
  • newType 同上,new字样,实现上需要保证是个新的实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卓修武

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值