effective解读-第一条
MR_程序猿刘 人气:0一、静态工厂创建对象代替构造器
好处
有名称,能见名知意。例如BigInteger的probablePrime方法
享元模式、单例模式中使用
享元模式:创建对象代价很高,重复调用已有对象,例如数据库连接等。享元模式是单例模式的一个拓展。
可以返回原类型的任何子类型
可以通过参数值添加业务逻辑返回不同对象,基于第3点
interface Demo {
static Demo getDemoByParam(Integer param) {
if (param > 0) {
return new BigDemo();
} else {
return new SmallDemo();
}
}
}
private static class BigDemo implements Demo {
}
private static class SmallDemo implements Demo {
}
可以返回不存在的类的对象,服务提供者框架例如JDBC,java1.6java提供一个服务提供者框架 java.util.ServiceLoader(JDBC早于ServiceLoader所以没有使用它)
服务提供者框架包括:
服务者接口,提供服务的接口如JDBC的Connection接口
服务提供者接口,获取服务提供者的接口如JDBC的Driver接口,如下是mysql提供的实
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
//我们在使用的时候 Class.forName("com.mysql.jdbc.Driver")会加载该启动,并调用服务提供者注册API进行注册驱动
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
}
}
服务提供者注册API(DriverManager.registerDriver())
//mysql生产厂方提供并使用它在我们加载其Driver的时候进行注册
服务访问API(DriverManager.getConnection())
//我们可以直接,加载Driver后我们可以通过它获取服务对象Connection
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/education5?serverTimezone=Asia/Shanghai","root","123456");
java.util.ServiceLoader方式:
//服务接口
public class Hello{
void hello();
}
public class DemoUtils {
//服务注册API和访问API,这里因为是demo所以卸载了一起
public static void hello(){
ServiceLoader<Hello> load = ServiceLoader.load(Hello.class);
for (Hello hello : load) {
hello.hello();
}
}
}//服务接口实现
public class HelloImpl1 implements Hello {
@Override
public void hello() {
System.out.println("HelloImpl1.hello");
}
public static void main(String[] args) { //测试代码
DemoUtils.hello();
}
}在classpath下创建对应接口目录的文件/META-INF/services/com.demo.Hello文件注册我们写的实现类即可
com.demo.Hello文件
com.demo.HelloImpl1
缺点
不包含共有或者受保护的构造器,导致无法被继承。这样也因祸得福,鼓励程序员使用组合而不是继承。
静态工厂方法一般和类或者接口分离出来,例如Collection和Collections。如果静态工厂方法所在的类没有提供API我们就很难找到类的实例化方法了。通过类或者接口注释并遵守命名规范来弥补这一劣势如下部分,实际使用过程中可以查询或者百度
from——类型转换方法,单个参数,返回一个像相对应的实例
of——聚合方法,带有多个参数,多个实例聚合成一个实例
instance或者newInstance 通过方法参数创建实例(也可以没有参数)
create或者newInstance 通过参数方法创建实例但是每次创建一个新的实例
加载全部内容