簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式( Simple Factory Pattern )用來定義一個(gè)工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類。因?yàn)樵诤?jiǎn)單工廠模式中用于創(chuàng)建實(shí)例的方法是靜態(tài)( static )方法,因此簡(jiǎn)單工廠模式又被稱為靜態(tài)工廠方法( Static Factory Method )模式,它屬于類創(chuàng)建型模式。
簡(jiǎn)單工廠模式的要點(diǎn)在于,當(dāng)你需要什么,只需要傳入一個(gè)正確的參數(shù),就可以獲取你所需要的對(duì)象,而無須知道其創(chuàng)建細(xì)節(jié)。簡(jiǎn)單工廠模式結(jié)構(gòu)比較簡(jiǎn)單,其核心是工廠類的設(shè)計(jì)。其結(jié)構(gòu)圖如下所示。

在簡(jiǎn)單工廠模式結(jié)構(gòu)圖中包含如下幾個(gè)角色。
- Factory(工廠角色):工廠角色即工廠類,它是簡(jiǎn)單工廠模式的核心,負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有產(chǎn)品實(shí)例的內(nèi)部邏輯; 工廠類可以被外界直接調(diào)用, 創(chuàng)建所需的產(chǎn)品對(duì)象;在工廠類中提供了靜態(tài)的工廠方法factoryMethod(),它的返回類型為抽象產(chǎn)品類型Product 。
- Product(抽象產(chǎn)品角色):它是工廠類所創(chuàng)建的所有對(duì)象的父類,封裝了各種產(chǎn)品對(duì)象的公有方法,它的引入將提高系統(tǒng)的靈活性,使得在工廠類中只需定義一個(gè)通用的工廠方法,因?yàn)樗袆?chuàng)建的具體產(chǎn)品對(duì)象都是其子類對(duì)象。
- ConcreteProduct(具體產(chǎn)品角色):它是簡(jiǎn)單工廠模式的創(chuàng)建目標(biāo),.所有被創(chuàng)建的對(duì)象都充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。每一個(gè)具體產(chǎn)品角色都繼承了抽象產(chǎn)品角色,需要實(shí)現(xiàn)在抽象產(chǎn)品中聲明的抽象方法。
來看一個(gè)簡(jiǎn)單工廠模式的例子
public class SimpleFactoryPattern {
public static void main(String[] args) {
//根據(jù)需要傳入相關(guān)的交通工具名稱,獲取交通工具實(shí)例
Vehicle vehicle = Factory.produce("car");
vehicle.run();
}
}
/**
* 工廠類
*/
class Factory{
//靜態(tài)方法,生產(chǎn)交通工具
public static Vehicle produce(String type) {
Vehicle vehicle = null;
if(type.equals("car")){
vehicle = new _Car();
return vehicle;
}
if(type.equals("bus")){
vehicle = new _Bus();
return vehicle;
}
if(type.equals("bicycle")){
vehicle = new _Bicycle();
return vehicle;
}
return vehicle;
}
}
/**
* 交通工具(抽象類)
*/
interface Vehicle{
void run();
}
/**
* 汽車(具體類)
*/
class Car implements Vehicle{
@Override
public void run() {
System.out.println("car is running...");
}
}
/**
* 公交車(具體類)
*/
class Bus implements Vehicle{
@Override
public void run() {
System.out.println("bus is running...");
}
}
/**
* 自行車(具體類)
*/
class Bicycle implements Vehicle{
@Override
public void run() {
System.out.println("bicycle is running...");
}
}
上述代碼中,交通工具都被抽象為Vehicle 類, 而Car、Bus 、Bicycle 類是Vehicle 類的實(shí)現(xiàn)類, 并實(shí)現(xiàn)Vehicle 的run方法,打印相關(guān)的信息。Factory 是工廠類,類中的靜態(tài)方法produce 根據(jù)傳入的不同的交通工具的類型,生產(chǎn)相關(guān)的交通工具,返回抽象產(chǎn)品類Vehicle 。上述代碼的類結(jié)構(gòu)如下所示。

簡(jiǎn)單工廠模式的主要優(yōu)點(diǎn)如下:
- 工廠類包含必要的判斷邏輯,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)產(chǎn)品類的實(shí)例,客戶端可以免除直接創(chuàng)建產(chǎn)品對(duì)象的職責(zé),而僅僅“消費(fèi)”產(chǎn)品,簡(jiǎn)單工廠模式實(shí)現(xiàn)了對(duì)象創(chuàng)建和使用的分離。
- 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對(duì)應(yīng)的參數(shù)即可,對(duì)于一些復(fù)雜的類名,通過簡(jiǎn)單工廠模式可以在一定程度減少使用者的記憶量。
簡(jiǎn)單工廠模式的主要缺點(diǎn)如下:
- 由于工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯,職責(zé)過重, 一旦不能正常工作,整個(gè)系統(tǒng)都會(huì)受到影響。
- 使用簡(jiǎn)單工廣模式勢(shì)必會(huì)增加系統(tǒng)中類的個(gè)數(shù)(引入了新的工廠類),增加了系統(tǒng)的復(fù)雜度和理解難度。
- 系統(tǒng)擴(kuò)展困難, 一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時(shí),有可能造成工廠邏輯過于復(fù)雜,不利于系統(tǒng)的擴(kuò)展和維護(hù)。
- 簡(jiǎn)單工廠模式由于使用了靜態(tài)工廠方法,造成工廠角色無法形成基于繼承的等級(jí)結(jié)構(gòu)。
工廠方法模式
在簡(jiǎn)單工廠模式中只提供一個(gè)工廠類,它需要知道每一個(gè)產(chǎn)品對(duì)象的創(chuàng)建細(xì)節(jié),并決定何時(shí)實(shí)例化哪一個(gè)產(chǎn)品類。簡(jiǎn)單工廠模式最大的缺點(diǎn)是當(dāng)有新產(chǎn)品要加入到系統(tǒng)中時(shí),必須修改工廠類,需要在其中加入必要的業(yè)務(wù)邏輯,這違背了“開閉原則” 。此外,在簡(jiǎn)單工廠模式中,所有的產(chǎn)品都由同一個(gè)工廠創(chuàng)建,工廠類職責(zé)較重,業(yè)務(wù)邏輯較為復(fù)雜,具體產(chǎn)品與工廠類之間的耦合度高,嚴(yán)重影響了系統(tǒng)的靈活性和擴(kuò)展性,而工廠方法模式則可以很好地解決這一問題。
在工廠方法模式中,不再提供一個(gè)統(tǒng)一的工廠類來創(chuàng)建所有的產(chǎn)品對(duì)象,而是針對(duì)不同的產(chǎn)品提供不同的工廠,系統(tǒng)提供一個(gè)與產(chǎn)品等級(jí)結(jié)構(gòu)對(duì)應(yīng)的工廠等級(jí)結(jié)構(gòu)。
工廠方法模式的定義:工廠方法模式(Factory Method Pattern)用來定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定將哪一個(gè)類實(shí)例化。工廠方法模式讓一個(gè)類的實(shí)例化延遲到其子類。工廠方法模式又簡(jiǎn)稱為工廠模式( Factory Pattern ),還可稱作虛擬構(gòu)造器模式( Virtual Constructor Pattern )或多態(tài)工廠模式( Polymorphic Factory Pattern )。工廠方法模式是一種類創(chuàng)建型模式。
工廠方法模式提供一個(gè)抽象工廠接口來聲明抽象工廠方法,而由其子類來具體實(shí)現(xiàn)工廠方法,創(chuàng)建具體的產(chǎn)品對(duì)象。工廠方法模式結(jié)構(gòu)如下所示。

在工廠方法模式結(jié)構(gòu)圖中包含如下幾個(gè)角色。
- Product(抽象產(chǎn)品類):它是定義產(chǎn)品的接口,是工廠方法模式所創(chuàng)建對(duì)象的超類型,也就是產(chǎn)品對(duì)象的公共父類。
- ConcreteProduct(具體產(chǎn)品類) : 它實(shí)現(xiàn)了抽象產(chǎn)品接口,某種類型的具體產(chǎn)品由專門的具體工廠創(chuàng)建,具體工廠和具體產(chǎn)品之間一一對(duì)應(yīng)。
- Factory(抽象工廠類):在抽象工廠類中,聲明了工廠方法( Factory Method ),用于返回一個(gè)產(chǎn)品。抽象工廠是工廠方法模式的核心,所有創(chuàng)建對(duì)象的工廠類都必須實(shí)現(xiàn)該接口。
- ConcreteFactory (具體工廠類) : 它是抽象工廠類的子類,實(shí)現(xiàn)了抽象工廠中定義的工廠方法,并可由客戶端調(diào)用,返回一個(gè)具體產(chǎn)品類的實(shí)例。
下面來看一個(gè)汽車與工廠實(shí)例。
public class FactoryMethodPattern {
public static void main(String[] args) throws Exception {
//生產(chǎn)汽車
Factory carFactory = new CarFactory();
Vehicle car= carFactory.produce();
car.run();
//生產(chǎn)公交車
Factory busFactory = new BusFactory();
Vehicle bus= busFactory.produce();
bus.run();
//生產(chǎn)自行車
BicycleFactory bicycleFactory = new BicycleFactory();
Vehicle bicycle= bicycleFactory.produce() ;
bicycle.run();
}
}
/**
*抽象工廠類
*/
interface Factory {
//生產(chǎn)
Vehicle produce();
}
/**
*汽車工廠
*/
class CarFactory implements Factory {
@Override
public Vehicle produce() {
return new Car();
}
}
/**
*公交車工廠
*/
class BusFactory implements Factory {
@Override
public Vehicle produce() {
return new Bus();
}
}
/**
*自行車工廠
*/
class BicycleFactory implements Factory {
@Override
public Vehicle produce() {
return new Bicycle();
}
}
/**
*交通工具
*/
interface Vehicle {
void run();
}
/**
*汽車
*/
class Car implements Vehicle {
@Override
public void run () {
System.out.println (”car is running . . . ”);
}
}
/**
*公交車
*/
class Bus implements Vehicle {
@Override
public void run () {
System.out.println (”bus is running . . . ”);
}
}
/**
*自行車
*/
class Bicycle implements Vehicle {
@Override
public void run () {
System.out.println (”bicycle is running . . . ”);
}
}
上述代碼中,Vehicle 類是抽象產(chǎn)品類,而Car 、Bus 、Bicycle類是具體產(chǎn)品類,并且實(shí)現(xiàn)Vehicle 類的run 方法。每一種具體產(chǎn)品類都有一一對(duì)應(yīng)的工廠類CarFactory 、BusFactory 、BicycleFactory 等,所有的工廠都有共同的抽象父類Factory。汽車與工廠具體的類結(jié)構(gòu)如下圖所示。

與簡(jiǎn)單工廠模式相比, 工廠方法模式最重要的區(qū)別是引入了抽象工廠角色,抽象工廠可以是接口,也可以是抽象類或者具體類。在抽象工廠中聲明了工廠方法但并未實(shí)現(xiàn)工廠方法, 具體產(chǎn)品對(duì)象的創(chuàng)建由其子類負(fù)責(zé), 客戶端針對(duì)抽象工廠編程,可在運(yùn)行時(shí)再指定具體工廠類,具體工廠類實(shí)現(xiàn)了工廠方法, 不同的具體工廠可以創(chuàng)建不同的具體產(chǎn)品。