工厂模式
实例化对象不使用 new,用工厂方法代替;
将选择实现类、创建对象统一管理和控制,从而将调用者跟我们的实现类解耦
- 简单工厂模式(静态工厂模式)
- 在创建一个对象时不向用户暴露内部细节,并提供一个创建对象的通用接口;
- 虽然某种程度上不符合设计原则(开闭原则),但实际使用最多。
- 工厂方法模式
- 定义一个创建对象的借口,但由子类决定要实例化哪个类。工厂方法吧实例化操作推迟到子类;
- 不修改已有类的前提下,通过增加新的工厂类实现扩展
- 抽象工厂模式
- 围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂;
- 不可以增加产品,可以增加一个产品族
应用场景
JDK 中 Calendar的 getInstance方法
JDBC 中的 Connection对象的获取
Spring 中 IOC容器创建管理 bean对象
反射中 Class对象的 newInstance方法
1. 简单工厂
在创建一个对象时不向用户暴露内部细节,并提供一个创建对象的通用接口。
public interface Car {
void name();
}
public class Porsche implements Car {
@Override
public void name() {
System.out.println("保时捷!");
}
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光!");
}
}
简单工厂类实现
public class CarFactory{
public static Car createCar(String car){
if("Porsche".equals(car)){
return new Porsche();
} else if("WuLing".equals(car)){
return new WuLing();
} else{
return null;
}
}
}
用户调用
public class Consumer {
public static void main(String[] args) {
Car car1 = CarFactory.createCar("Porsche");
Car car2 = CarFactory.createCar("WuLing");
car1.name();
car2.name();
}
}
但是,如果车工厂多了一个车的实现,就要修改原来的车工厂代码,这里就违反了开闭原则:对扩展开放,对修改关闭
public class CarFactory{
public static Car createCar(String car){
if("Porsche".equals(car)){
return new Porsche();
} else if("WuLing".equals(car)){
return new WuLing();
} else if("DaZhong".equals(car)){
return new DaZhong();
} else{
return null;
}
}
}
2. 工厂方法
定义一个创建对象的借口,但由子类决定要实例化哪个类。工厂方法吧实例化操作推迟到子类
public interface Car {
void name();
}
public interface CarFactory {
Car createCar();
}
public class Porsche implements Car {
@Override
public void name() {
System.out.println("保时捷!");
}
}
public class PorscheFactory implements CarFactory {
@Override
public Car createCar() {
return new Porsche();
}
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光!");
}
}
public class WuLingFactory implements CarFactory {
@Override
public Car createCar() {
return new WuLing();
}
}
使用每个车的车工厂来获取车,此时再增加车,也不用修改原来的代码,遵守了开闭原则
public class Consumer {
public static void main(String[] args) {
Car car1 = new PorscheFactory().createCar();
Car car2 = new WuLingFactory().createCar();
car1.name();
car2.name();
}
}
但是每次新增一辆车,就要多写好几个类,所以其实简单工厂类使用更多。
3. 抽象工厂
抽象工厂提供了一个创建一系列相关或者相关依赖对象的借口,无需指定它们具体的类
- 适用场景
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节;
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码;
- 提供一个产品类的库,所有的产品以同样的借口出现,从而使得客户端不依赖于具体的实现
- 优点
- 具体产品在应用层的代码隔离,无需关心创建的细节;
- 将一个系列的产品统一到一起创建
- 缺点
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难(开闭原则);
- 增加了系统的抽象性和理解难度