## **模式的定义**
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中
## **简单工厂模式**
需求:假设一个汽车工厂需要生成多种品牌的汽车
简单工厂模式的代码实现:
1. 定义统一的汽车生产接口
```
public interface Car {
void create();
}
```
2. 实现不同品牌的生产方法
```
// 生产奥迪品牌的汽车
public class AdCar implements Car{
@Override
public void create() {
System.out.println("生产奥迪汽车");
}
}
// 生产宝马品牌的汽车
public class BmwCar implements Car {
@Override
public void create() {
System.out.println("生产宝马品牌的汽车");
}
}
```
3. 创建工厂
```
public class CarFactory {
public static Car createCar(String brandName) {
if (brandName.equals("奥迪")) {
return new AdCar();
}
if (brandName.equals("宝马")) {
return new BmwCar();
}
return null;
}
}
```
4. 客户端调用
```
public static void main(String[] args) {
Car adCar = CarFactory.createCar("奥迪");
Car bmwCar = CarFactory.createCar("宝马");
adCar.create();
bmwCar.create();
}
```
## **工厂方法模式**
上面的案例中,假设这个工厂会经常性的添加一些品牌,那么就需要不停的更新维护这个总的工厂,但是实际上每次添加一个品牌都是会添加一个新的车间来执行生产,那么为了不用频繁的维护这个总工厂,我们只需要关注新创建的车间就可以了。
工厂方法的代码实现:
1. 定义统一的汽车生产接口
```
public interface Car {
void create();
}
```
2. 定义工厂
```
public interface CarFactory {
Car createCar();
}
```
3. 实现各个品牌的工厂具体方法
```
// 奥迪
public class AdCarFactory implements CarFactory {
@Override
public Car createCar() {
return new AdCar();
}
}
// 宝马
public class BmwCarFactory implements CarFactory {
@Override
public Car createCar() {
return new BmwCar();
}
}
```
4. 客户端调用
```
public static void main(String[] args) {
Car adCar = new AdCarFactory().createCar();
Car bmwCar = new BmwCarFactory().createCar();
adCar.create();
bmwCar.create();
}
```
如此一来,下次再添加一个品牌汽车时,创建对于的具体工厂方法就好了,扩展性刚刚的。
## **抽象工厂模式**
上面的案例中,我们生产汽车的时候只是简单的用了create,但是实际生产中是一系列的生产要素的组合,例如说生产一辆汽车包括:发动机、轮胎等等,并且各个生产要素都可以是多种不同的型号。
```
发动机: 型号A、型号B
轮胎:型号A、型号B
假设
生产宝马需要:型号A的发动机 + 型号B的轮胎
生产奥迪需要:型号B的发动机 + 型号A的轮胎
那么我们该如何优雅的生产呢?
```
继续改造代码
1. 定义统一的发动机接口
```
public interface Engine {
// 最大转速
void MaxSpeed();
// 手动挡/自动挡
void Type();
}
```
2. 定义统一的轮胎接口
```
// 轮胎
public interface Tire {
void create();
}
```
3. 实现A型号和B型号的发动机方法
```
public class EngineA implements Engine {
@Override
public void MaxSpeed() {
System.out.println("最大支持2000转速");
}
@Override
public void Type() {
System.out.println("自动挡");
}
}
public class EngineB implements Engine {
@Override
public void MaxSpeed() {
System.out.println("最大支持3000转速");
}
@Override
public void Type() {
System.out.println("手动挡");
}
}
```
4. 实现A型号和B型号的轮胎方法
```
public class TireA implements Tire{
@Override
public void create() {
System.out.println("A型轮胎");
}
}
public class TireB implements Tire {
@Override
public void create() {
System.out.println("B型轮胎");
}
}
```
5. 定义抽象工厂
```
public interface CarFactory {
// 生产发动机
Engine createEngine();
// 生产轮胎
Tire createTire();
}
```
6. 实现具体的奥迪工厂方法
```
public class AdCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Tire createTire() {
return new TireA();
}
}
```
7. 实现具体的宝马工厂方法
```
public class BmwCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Tire createTire() {
return new TireB();
}
}
```
8. 客户端调用
```
public static void main(String[] args) {
CarFactory adCarFactory = new AdCarFactory();
Engine adEngine = adCarFactory.createEngine();
adEngine.MaxSpeed();
adEngine.Type();
Tire adTire = adCarFactory.createTire();
adTire.create();
CarFactory bmwCarFactory = new BmwCarFactory();
Engine bmwEngine = bmwCarFactory.createEngine();
bmwEngine.MaxSpeed();
bmwEngine.Type();
Tire bmwTire = bmwCarFactory.createTire();
bmwTire.create();
}
```
## **三种工厂模式的区别**
观察发现,简单工厂和工厂模式都是构建基于"汽车"这一层面的产品,工厂模式相对于简单工厂更具有扩展性。
而抽象工厂模式针对的是多个产品等级结构的。
| 工厂方法模式 | 抽象工厂模式 |
| --- | --- |
| 针对一个产品等级结构 | 针对多个产品等级结构 |
| 一个抽象产品类(car) | 多个抽象产品类(Engine、Tire) |
| 可以派生出多个产品类(AdCar、BmwCar) | 每个产品类都可以派生出多个产品类(EngineA、EngineB、TireA、TireB) |
| 一个抽象工厂类、可以派生出多个具体工厂类(AdCarFactory、BmwCarFactory ) | 一个抽象工厂类、可以派生出多个具体工厂类(AdCarFactory、BmwCarFactory ) |
| 每个具体工厂类只能创建一个产品实例 | 每个具体工厂类可以创建多个产品实例 |
最后一点可能会有点疑问?抽象工厂模式中每个具体工厂类如何创建多个产品实例?我们来看看代码AdCarFactory类如何创建多个产品实例?
1. 修改抽象工厂接口,在发动机的抽象方法中加入参数type
```
public interface CarFactory {
// 生产发动机
Engine createEngine(String type);
// 生产轮胎
Tire createTire();
}
```
2. 修改AdCarFactory工厂类
```
public class AdCarFactory implements CarFactory {
@Override
public Engine createEngine(String type) {
if (type.equals("A")) {
return new EngineA();
} else {
return new EngineB();
}
}
@Override
public Tire createTire() {
return new TireA();
}
}
```
3. 客户端调用
```
public static void main(String[] args) {
CarFactory adCarFactory = new AdCarFactory();
Engine engineA = adCarFactory.createEngine("A");
Engine engineB = adCarFactory.createEngine("B");
}
```
通过AdCarFactory类可以创建不同的产品实例。