什么是工厂方法模式
父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。
用模板方法模式来构建生成实例的工厂,就是工厂方法模式。
例子
制作身份证卡,工厂类、产品类、身份证工厂类、身份证类
Factory
package CreationPattern.FactoryMode;
/**
* 工厂类
*/
public abstract class Factory {
/**
* 创建产品的模板方法
*/
public final Product create(String owner){
Product p = createProduct(owner);
registerProduct(p);
return p;
}
public abstract void registerProduct(Product product);
public abstract Product createProduct(String owner);
}
IDCardFacroty
package CreationPattern.FactoryMode;
import java.util.ArrayList;
import java.util.List;
/**
* 创建ID卡的工厂
*/
public class IDCardFacroty extends Factory{
/**
* 注册用户集合
*/
private List owners = new ArrayList();
@Override
public void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
}
@Override
public Product createProduct(String owner) {
IDCard idCard = new IDCard(owner);
return idCard;
}
public List getOwners(){
return owners;
}
}
Product
package CreationPattern.FactoryMode;
/**
* 产品类
*/
public abstract class Product {
public abstract void use();
}
IDCard
package CreationPattern.FactoryMode;
/**
* ID卡类
*/
public class IDCard extends Product {
private String owner;
public IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
}
@Override
public void use() {
System.out.println("使用" + owner + "的ID卡");
}
public String getOwner() {
return owner;
}
}
Main
package CreationPattern.FactoryMode;
import java.util.List;
/**
* Main
*/
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFacroty();
Product c1 = factory.create("张三");
Product c2 = factory.create("李四");
Product c3 = factory.create("王五");
System.out.println("--------------");
c1.use();
c2.use();
c3.use();
System.out.println("--------------");
List owners = ((IDCardFacroty) factory).getOwners();
owners.forEach(System.out::println);
}
}
结果
总结
可以看到,使用工厂方法模式忽略了实例创建的细节,不使用new关键字去生成实例,而是调用生成实例专用的方法,这样可以防止父类与其他具体类耦合。
在Java标准库中频繁的使用静态工厂方法去生成实例,例如List.of()、Integer.valueOf(),在Integer.valueOf底层实现中,使用了缓存
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
而使用工厂方法就不需要关注这个实例是new获得还是缓存获得。