用静态工厂方法代替构造器以及服务提供者框架
为什么要使用静态工厂方法代替构造器?
优点:
- 可以确切描述返回什么对象,避免构造不规范
- 可以不必在每次调用时都创建新的对象
- 它可以返回该类的子类对象,程序更加灵活
- 返回的对象可以根据指定参数生成,参数不同,对象就不同
- 返回对象所属的类,可以与该类无关
实例化对象时,不要第一反应就是提供公有构造器,而不先考虑静态工厂方法
实例
概念都是不好理解的,通过实例来理解概念
参考自知乎用户,Uncle-lv https://zhuanlan.zhihu.com/p/112986695
假如一所大学有三个学院,信息学院,财经学院,工程学院,我们不想把创建学院交给外部,因为外部不了解该大学的结构,
可能创造一个不存在的学院,但是,我们又要提供创建学院的接口,这时候该怎么做?
这时候静态工厂方法就起作用了,类提供一个公有的静态工厂方法
【优点1】:使用静态工厂模式确定要返回什么对象,避免构造不规范
public class College{
private String name;
//私有化构造方法
private College(String name){
this.name = name;
}
//提供3种创建方法
public static College getInfomationCollege(){
return new College("信息学院");
}
public static College getFinanceCollege(){
return new College("财经学院");
}
public static College getEngineerCollege(){
return new College("工程学院");
}
public String getName(){
return name;
}
}
【优点2】:可以不必在每次调用时都创建新的对象
//有时候我需要多次调用静态方法得到该对象,但是学院只要创建一个,我们先调用一下
College college1 = College.getEngineerCollege();
College college2 = College.getEngineerCollege();
System.out.println(college1 == college2); //false
//很明显,生成了两个学院,这不符合我们的需求,所以第一段代码,还有改进的空间
private static College infomationCollege;
public static College getInfomationCollege() {
//单例模式
if(College.infomationCollege == null){
return new College("信息学院");
}
return College.infomationCollege;
}
//再来测试一下
College college1 = College.getEngineerCollege();
College college2 = College.getEngineerCollege();
System.out.println(college1 == college2); //true
有一个人的类,我们通过静态工厂方法生成其子类
【优点3】: 它可以返回该类的子类对象,程序更加灵活
这样我们返回的都是Person的子类对象,我们不必知道Adult类和Child类的存在,程序更加灵活
【优点4】:所放回的对象的类何以随着每次调用而发生变化,这取决于静态工厂方法的参数值
每次返回的类型因参数的都不同
public class Person {
protected int age;
public Person getPerson(int age){
if(age < 18 && age >= 0){
return new Adult(age);
}
if(age > 18){
return new Child(age);
}
return null;
}
private static class Child extends Person{
public Child(int age){
this.age = age;
System.out.println("我是一个"+ age +"岁的小孩");
}
}
//成员内部类
private static class Adult extends Person{
public Adult(int age){
this.age = age;
System.out.println("我是一个"+ age +"岁的大人");
}
}
}
【优点5】:
总结
1、什么时候使用静态工厂方法?
- 当一个类需要多个相同名字的构造器,可以通过静态工厂方法返回指定的类
- 如果程序经常请求创建相同的对象
- 适用基于接口的框架
2、缺点
- 构造器私有化之后,就不能被继承了