✯ 面向对象设计原则
- 对接口编程而不是对实现编程
- 优先使用对象组合而不是继承
介绍说明
工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
➳ 作用:实现了创建者和调用者的分离;主要解决接口选择的问题。
▎工厂模式核心本质:
- 实例化对象不使用new,而是用工厂方法代替
- 将选择实现类型,创建对象统一管理和控制。从而将掉哟哦你跟着跟我们实现类解藕
▎三种模式:
- 简单工厂模式:用来生产同一等级结构中的任意产品(支持增加新产品,需覆盖已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
☛ 应用场景
- JDK中Calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
简单工厂模式(静态工厂模式)
某种程度上不符合设计原则规范没,但使用它最多。
应用实例: 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现(创建过程在其子类执行)
1. 定义一个车类接口
public interface Car {
public void name();
}
2.编写两个实现类去实现Car接口,分别是:五菱汽车、大众汽车
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱汽车!");
}
}
public class DaZhong implements Car{
@Override
public void name() {
System.out.println("大众汽车!");
}
}
3.编写一个车的工厂类,消费者从工厂里提取具体车
// 也叫静态工厂模式,不满足开闭原则,增加一个产品就要修改原代码
public class CarFactory {
// 方式一:根据类型返回不同的car
public static Car getCar(String type){
if("五菱".equals(type)){
return new WuLing();
}else if("大众".equals(type)){
return new DaZhong();
}else {
return null;
}
}
// 方式二,拒绝臃肿的if else代码,相对于较好扩展,但也是增加一个产品需要改代码
public static Car getWuLingCar(){
return new WuLing();
}
public static Car getDaZhongCar(){
return new DaZhong();
}
}
4.测试类
/**
简单工厂模式:用来生产同一等级结构中的任意产品(支持增加新产品,需要扩展已有代码)
*/
public class Zmain {
public static void main(String[] args) {
// 1.传统方式,需要去new每一个具体的实现类
// 假设此类初始化需要很多额外的参数,那需要一个个传参数进去,代码不美观
//Car car = new WuLing();
//Car car2 = new DaZhong();
// 2.使用工厂模式获取具体类,特点是只关心去工厂里拿,而不new具体实现
Car car = CarFactory.getCar("五菱");
Car car2 = CarFactory.getDaZhongCar();
car.name();
car2.name();
}
}
5.运行结果
➳ 结论:简单工厂模式无非就是去工厂里获取具体类,而不是直接暴露的new具体类,消费者只在车工厂里获取具体车。
但这也有一个非常突出的缺点,假设我此时扩展一个特斯拉车辆,那每次都需要去改造CarFactory车工厂里的代码,无脑补if else代码,或者再写一个获取特斯拉车的方法,不方便横向扩展,也不符合开闭原则(对扩展开放,对修改关闭)
工厂方法模式
在不修改已有类的情况下,通过增加新的工厂类实现扩展
工厂方法模式是简单工厂模式的升级版本,符合开闭原则,但同样的代码维护量也更多了,核心思想是为每一个车都制造一个自己的工厂,消费者从各个工厂里提取车
1. CarFactory 类改造
/**
* 定义一个公共factory接口,新增加一个产品去实现这个规范的工厂接口,而无需改这个接口
*/
public interface CarFactory {
Car getCar();
}
2.每一个车都去实现公共的CarFactory类,自己搭建一个工厂类
public class WuLingFactory implements CarFactory{
@Override
public Car getCar() {
return new WuLing();
}
}
public class DaZhongFactory implements CarFactory{
@Override
public Car getCar() {
return new DaZhong();
}
}
此时我们扩展一个特斯拉车辆
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉!");
}
}
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
3.测试类
public class Zmain {
public static void main(String[] args) {
// 需要什么车,就从什么车工厂里去获取
Car car = new WuLingFactory().getCar();
Car car2 = new DaZhongFactory().getCar();
car.name();
car2.name();
// 增加一个特斯拉车,每扩展一个产品,写一个自己的factory,而无需改原代码
Car car3 = new TeslaFactory().getCar();
car3.name();
}
}
4.运行结果
➳ 结论:工厂方法模式符合开闭原则,增加新的产品不涉及修改原已存在的代码,支持横向拓展,但是从代码、结构、编程、管理四个复杂度维度来说,简单工厂模式都是最简单明了的,工厂方法模式代码量变得臃肿,根据情况场景去选择哪种模式应用。