作用与本质
作用:实现了创建者与调用者的分离。
核心本质:
- 实例化对象不使用new,用工厂方法代替。
- 将选择实现类,创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。
详细分类
-
简单工厂模式
用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有的代码)
-
工厂方法模式
用来生产 同一等级结构中的固定产品(支持增加任意产品)
-
抽象工厂模式
围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
这些文字很无聊哈。
还是直接看代码吧。
汽车例子讲解工厂模式化
//Car接口
public interface Car {
void name();
}
//具体的一个车(五菱宏光)去实现Car接口
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
//具体的一个车(特斯拉)去实现Car接口
public class Tesla implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
//消费者
public class Consumer {
public static void main(String[] args) {
Car car = new WuLing();
Car car2 = new Tesla();
car.name();
car2.name();
}
}
上面的代码是我们没有使用工厂模式来实现的,那么我们现在要怎么使用工厂模式呢?
简单来说,就是创建一个CarFactory,我们不去new,通过CarFactory得到Car。
//简单工厂模式又叫静态工厂模式
//增加一个产品,还是得修改原来的代码,这样是有弊端的。
//不满足开闭原则
public class CarFactory {
//方法一
public static Car getCar(String car) {
if(car.equals("五菱宏光")) {
return new WuLing();
} else if(car.equals("特斯拉")) {
return new Tesla();
} else {
return null;
}
}
//方法二
public static Car getWuLing() {
return new WuLing();
}
public static Car getTesla() {
return new Tesla();
}
}
//简单工厂模式
public class Consumer {
public static void main(String[] args) {
//简单工厂模式
Car car = CarFactory.getCar("五菱宏光");
Car car2 = CarFactory.getCar("特斯拉");
car.name();
car2.name();
}
}
在没有使用工厂模式之前,我们需要去new,如果wuling和Tesla有很多参数,在new的时候就麻烦不少。
但是使用工厂模式,就不用关心底层了,我不管他是怎么实现的,我只管交给车车工厂就行了,我只要告诉他我要什么车,由车工厂去帮你。这样是不是就省事很多!
当然也有一定的问题,不满足开闭原则,要增加一个产品,得修改原来的代码。
那怎么去解决这个问题呢?工厂方法!
public interface Car {
void name();
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
public class Tesla implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
//工厂方法模式
public interface CarFactory {
Car getCar();
}
//具体的车工厂(wuling)去实现 CarFactory
public class WuLingFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLing();
}
}
//具体的车工厂(tesla)去实现 CarFactory
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}
//消费者直接去具体的车工厂拿车即可。
public class Consumer {
public static void main(String[] args) {
Car car = new WuLingFactory().getCar();
Car car2 = new TeslaFactory().getCar();
car.name();
car2.name();
}
}
现在我们要增加一个产品,如摩拜单车,那么不需要更改原来的代码,我们只需增加如下 即可。
public class MoBai implements Car{
@Override
public void name() {
System.out.println("摩拜单车");
}
}
public class MoBaiFactory implements CarFactory {
@Override
public Car getCar() {
return new MoBai();
}
}
public class Consumer {
public static void main(String[] args) {
Car car3 = new MoBaiFactory().getCar();
car3.name();
}
}
通过一个图再梳理一下:
你想要任意产品都可以,不需更改原来的代码。但是我们也看到代码量比简单工厂要多。
小结
从以下几个方面对比一下简单工厂与工厂方法:
- 结构复杂度:简单工厂更好
- 代码复杂度:简单工厂更好
- 编程复杂度:简单工厂更好
- 管理上的复杂度:简单工厂更好
根据设计原则:工厂方法模式。
根据实际开发:简单工厂模式。
应用场景
- JDK中的Calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
厂方法:
- 结构复杂度:简单工厂更好
- 代码复杂度:简单工厂更好
- 编程复杂度:简单工厂更好
- 管理上的复杂度:简单工厂更好
根据设计原则:工厂方法模式。
根据实际开发:简单工厂模式。
应用场景
- JDK中的Calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
抽象工厂模式被单分出来讲解。见下一篇文章。