笔记
-
建议用静态构造方法来代替 构造函数。
优点- 静态工厂方法可以取有意义的名字描述其用途,而构造函数只能是类的名字。
-
静态工厂方法并不要求每次调用都创建新对象,可以返回缓存的对象实例。
通过应用这种方法,我们可以严格控制系统中保留哪些对象实例。对应的类也被称作是“instance-controlled”。同时这种技术也是“Flyweight”设计模式的基础。
- 静态工厂方法可以返回方法定义的返回类型的子类的实例。
应用这种技术可以实现“基于接口的框架(interface-based frameworks)”。Collections类里有很多这样的静态工厂方法:返回做了限制或修改的集合类实例,这些实例没有外部可方法的具体的类定义,只能通过接口来引用。
Java8及以后版本中,接口可以定义public访问权限的静态方法,使得静态工厂方法的实现更为简单。但是不允许定义private类型的静态方法,这种限制使得静态工厂方法不能封装一些内部子方法,需要将子方法定义到伴随或者工具类中。
Java9则放开了这种限制。 - 静态工厂方法可以根据参数的不同返回不同类型的对象。
当然,这些类型都是方法签名中返回类型的子类。我们可以根据需要变化内部的实现。客户不用感知其中的变化。当然,这也是面向接口编程的好处。 - 静态工厂方法可以返回还不存在的对象。
这种形式的静态工厂方法是“service provider frameworks”的基础。
服务提供框架有几个组成部分:1. 服务接口(service interface),代表一种实现。2. 服务提供者注册API(provider registration API),用来注册实现。3. 服务获取API(service access API),使用者用来获取服务的实例。使用者可以传入查询条件来获取目标服务实现。
JDBC接口是这种框架的典型实现。JDK6以后提供了一种通用的实现:java.util.ServiceLoader
。
缺点
- 为了控制仅通过调用工厂静态方法来创建对象实例,不得不将类的构造方法的访问权限置为private,这些类不能再被继承了。
- 静态工厂方法在文档支持方面可能没有构造方法好。使用静态工厂方法实例化的类,没有公共的构造方法,所以api文档中不会有构造方法的说明,程序员难以找到实例化的方法。解决办法是遵循通用的静态工厂方法的命名习惯。
理解与思考
- 代码的可读性很重要。晦涩难懂的代码,不易维护。所以在给方法和类命名的时候,尤其要谨慎,遵循大家都接受,都看的懂的原则。静态工厂方法,在这方面要比构造函数好。
- 静态工厂方法,通常是用在面向接口编程中。外部使用接口来引用创建好的对象。工厂方法内可以很好的封装实现。