## **模式的定義**
定義一個創建產品對象的工廠接口,將產品對象的實際創建工作推遲到具體子工廠類當中
## **簡單工廠模式**
需求:假設一個汽車工廠需要生成多種品牌的汽車
簡單工廠模式的代碼實現:
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類可以創建不同的產品實例。