更新时间:2022-11-24 10:00:59 来源:极悦 浏览604次
静态工厂模式是一种改进的获取实例的方法。
通常我们会使用new关键字调用类的构造方法来创建一个对象,静态工厂模式相对于传统的创建对象的方式有以下优点:
当一个类的构造方法有非常多的参数或被重载过很多次的话,因为JAVA对构造方法命名的规定(与类名相同),我们必须编写多个命名相同但实际不同的构造函数,在创建对象时很难区分我们应该调用哪个构造方法。
比如在实际生产中,我们会经常见到以下方法:
newInstance():获取一个新的对象
valueOf():获取一个值为..的对象
getInstance():获取一个对象缓存池中的对象或单例对象
甚至我们可以更加细分,比如有一个Person类,我们想根据年龄来获取不同的对象,则可有如下静态工厂方法:
getChild():获取一个儿童对象
getOld():获取一个老年对象
getYouth():获取一个青年对象
等等,比起new关键字,显然使用上述方法获取对象更加具有可读性,使我们对创造的实例类型更可控。
当一个类的对象会被频繁使用,且没有必要在每次使用时都生成新的对象时,我们会考虑使用单例模式。单例模式大多是由静态工厂实现的,我们可以在工厂内部控制新生成实例或返回已有实例。
比如,DCL单例模式获取对象时就是采用了静态工厂:
public class Car {
//构造函数私有,禁止通过常规方式实例化
private Car(){}
//单例对象的引用
static volatile Car car=null;
//DCL获取单例对象,静态工厂方法
static Car getInstance(){
if(car==null){
synchronized(Car.class){
if(car==null){
car=new Car();
}
}
}
return car;
}
private Object readResolve() {
return getCar();
}
}
我们可以通过静态工厂返回一个类型的所有子类,可以更加灵活的获取实例。这也符合了两大设计原则:里氏替换原则与依赖倒置原则。即所有父类可以出现的地方子类也可以出现,以及类的使用方不应该依赖具体的实现类,而应该依赖继承链的顶端(接口或抽象类),即依赖抽象。
从Car中我们可以获取Bus和Taxi两个子类的实例,其它类在使用时只需维护一个Car的引用,至于具体用Bus还是用Taxi只由获取实例的那行代码决定,我们可以在只更换实例的获取而不改变其它代码(业务逻辑)的情况下修改代码。
public class Car{
public static Car getBus(){
return new Bus();
}
public static Car getTaxi(){
return new Taxi();
}
}
public class bus extends Car{
}
public class taxi extends Car{
}
这条主要是针对带泛型类的繁琐声明而说的,需要重复书写两次泛型参数:
Map<String,Date> map = new HashMap<String,Date>();
不过自从 java7 开始,这种方式已经被优化过了 —— 对于一个已知类型的变量进行赋值时,由于泛型参数是可以被推导出,所以可以在创建实例时省略掉泛型参数。
Map<String,Date> map = new HashMap<>();
所以这个问题实际上已经不存在了。大家如果想了解更多相关知识,不妨来关注一下本站的Java设计模式,里面还有更丰富的知识等着大家去学习,相信对大家一定能够有所帮助。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习