1. 工廠方法模式簡介
工廠方法模式(Factory Method Pattern)是創(chuàng)建型的設(shè)計模式,和簡單工廠模式比起來,它去掉了工廠類創(chuàng)建產(chǎn)品對象的方法的靜態(tài)屬性,如此以來,集中在工廠類的壓力,便可以由不同的子類來分擔(dān)。工廠方法模式包括4個角色。
● 抽象產(chǎn)品(Product):它是定義產(chǎn)品的接口,是具體產(chǎn)品的父類,是工廠創(chuàng)建的對象類型,在java中一般有抽象類或者接口來實現(xiàn)。
● 具體產(chǎn)品(ConcreteProduct):它實現(xiàn)了抽象產(chǎn)品接口,一種具體產(chǎn)品由專門的具體工廠創(chuàng)建,具體工廠和具體產(chǎn)品之間一一對應(yīng)。
● 抽象工廠(Factory):在抽象工廠類中,聲明了工廠方法(Factory Method),用于返回一個產(chǎn)品。抽象工廠是工廠方法模式的核心,所有創(chuàng)建對象的工廠類都必須實現(xiàn)該接口。
● 具體工廠(ConcreteFactory):它是抽象工廠類的子類,實現(xiàn)了抽象工廠中定義的工廠方法,并可由客戶端調(diào)用,返回一個具體產(chǎn)品類的實例。
2.工廠方法舉例
下面我們講舉一個汽車生產(chǎn)的例子,它們的對應(yīng)關(guān)系如下。

| 類名 | 角色 | 說明 |
|---|---|---|
| Vehicle | 抽象產(chǎn)品 | 機動車類 |
| C200 | 具體產(chǎn)品 | 奔馳C200機動車 |
| Bmw330 | 具體產(chǎn)品 | 寶馬330機動車 |
| VehicleFactory | 抽象工廠 | 機動車工廠 |
| BenzFactory | 具體工廠 | 負責(zé)生產(chǎn)C200 |
| BmwFactory | 具體工廠 | 負責(zé)生產(chǎn)Bmw330 |
| FactoryMethodMain | 客戶端 | 調(diào)用發(fā)起類 |
Vehicle接口類
/**
* 機動車
* 抽象產(chǎn)品類
*/
public interface Vehicle {
// 所有的機動車都可以跑
void run();
}
C200 產(chǎn)品類
/**
* 奔馳C200
* 具體產(chǎn)品類
*/
public class C200 implements Vehicle {
@Override
public void run() {
System.out.println("C200奔跑在路上。");
}
}
Bmw330 產(chǎn)品類
/**
* 寶馬 Bmw330
* 具體產(chǎn)品類
*/
public class Bmw330 implements Vehicle {
public void run() {
System.out.println("Bmw330奔跑在路上。");
}
}
VehicleFactory 抽象工廠類
/**
* 機動車工廠
* 抽象工廠類。 也可以使用abstract class,同時提供模式實現(xiàn)。
*/
public interface VehicleFactory {
// 生產(chǎn)機動車
Vehicle produce();
}
BenzFactory 具體工廠類
/**
* 奔馳工廠,生產(chǎn)C200機動車。
* 具體工廠類。
*/
public class BenzFactory implements VehicleFactory {
@Override
public Vehicle produce() {
return new C200();
}
}
BmwFactory 具體工廠類
/**
* 寶馬工廠,生產(chǎn)Bmw330機動車。
* 具體工廠類。
*/
public class BmwFactory implements VehicleFactory {
@Override
public Vehicle produce() {
return new Bmw330();
}
}
FactoryMethodMain 客戶端類
public class FactoryMethodMain {
public static void main(String[] args) {
// 不同的工廠,生產(chǎn)不同的機動車
VehicleFactory benzFactory = new BenzFactory();
Vehicle benz = benzFactory.produce();
benz.run();
// 可以通過配置文件的方式,解耦客戶端類和具體的工廠類。
VehicleFactory bmwFactoryFactory = new BmwFactory();
Vehicle bmw = bmwFactoryFactory.produce();
bmw.run();
}
}
3. 工廠方法模式總結(jié)
優(yōu)點
工廠方法模式和簡單工廠模式相比,繼承了優(yōu)點,彌補了不足;它們生產(chǎn)的產(chǎn)品是同一種產(chǎn)品,使客戶端不必知道創(chuàng)建產(chǎn)品對象的細節(jié),甚至是類名。
工廠方法模式充分體現(xiàn)了java的多態(tài)性,即工廠角色和產(chǎn)品角色多態(tài),這使得工廠可以自主確定創(chuàng)建何種產(chǎn)品對象。
工廠方法模式具體較好的擴展性,當(dāng)系統(tǒng)需要加入新產(chǎn)品時,只需要添加了一個具體工廠和具體產(chǎn)品就好,不需要修改抽象工廠類和抽象產(chǎn)品類,也不需要修改其它具體工廠和具體產(chǎn)品類,對客戶端也完全沒有影響,符合開閉原則。
缺點
每增加一種新產(chǎn)品,就需要多寫2個類(1個具體產(chǎn)品+1個具體工廠);同時還提高了系統(tǒng)的抽象度,提高了理解代碼的難道。
(完)