簡單工廠模式
簡單工廠模式( Simple Factory Pattern )用來定義一個工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實例蒋困,被創(chuàng)建的實例通常都具有共同的父類扛芽。因為在簡單工廠模式中用于創(chuàng)建實例的方法是靜態(tài)( static )方法元潘,因此簡單工廠模式又被稱為靜態(tài)工廠方法( Static Factory Method )模式殿如,它屬于類創(chuàng)建型模式。
簡單工廠模式的要點在于茴扁,當你需要什么铃岔,只需要傳入一個正確的參數(shù),就可以獲取你所需要的對象峭火,而無須知道其創(chuàng)建細節(jié)毁习。簡單工廠模式結(jié)構(gòu)比較簡單,其核心是工廠類的設(shè)計躲胳。其結(jié)構(gòu)圖如下所示蜓洪。
在簡單工廠模式結(jié)構(gòu)圖中包含如下幾個角色纤勒。
- Factory(工廠角色):工廠角色即工廠類坯苹,它是簡單工廠模式的核心,負責實現(xiàn)創(chuàng)建所有產(chǎn)品實例的內(nèi)部邏輯摇天; 工廠類可以被外界直接調(diào)用粹湃, 創(chuàng)建所需的產(chǎn)品對象;在工廠類中提供了靜態(tài)的工廠方法factoryMethod()泉坐,它的返回類型為抽象產(chǎn)品類型Product 为鳄。
- Product(抽象產(chǎn)品角色):它是工廠類所創(chuàng)建的所有對象的父類,封裝了各種產(chǎn)品對象的公有方法腕让,它的引入將提高系統(tǒng)的靈活性孤钦,使得在工廠類中只需定義一個通用的工廠方法歧斟,因為所有創(chuàng)建的具體產(chǎn)品對象都是其子類對象。
- ConcreteProduct(具體產(chǎn)品角色):它是簡單工廠模式的創(chuàng)建目標偏形,.所有被創(chuàng)建的對象都充當這個角色的某個具體類的實例静袖。每一個具體產(chǎn)品角色都繼承了抽象產(chǎn)品角色,需要實現(xiàn)在抽象產(chǎn)品中聲明的抽象方法俊扭。
來看一個簡單工廠模式的例子
public class SimpleFactoryPattern {
public static void main(String[] args) {
//根據(jù)需要傳入相關(guān)的交通工具名稱队橙,獲取交通工具實例
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 類的實現(xiàn)類解总, 并實現(xiàn)Vehicle 的run方法,打印相關(guān)的信息姐仅。Factory 是工廠類倾鲫,類中的靜態(tài)方法produce 根據(jù)傳入的不同的交通工具的類型,生產(chǎn)相關(guān)的交通工具萍嬉,返回抽象產(chǎn)品類Vehicle 乌昔。上述代碼的類結(jié)構(gòu)如下所示。
簡單工廠模式的主要優(yōu)點如下:
- 工廠類包含必要的判斷邏輯壤追,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品類的實例磕道,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的職責,而僅僅“消費”產(chǎn)品行冰,簡單工廠模式實現(xiàn)了對象創(chuàng)建和使用的分離溺蕉。
- 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對應(yīng)的參數(shù)即可悼做,對于一些復(fù)雜的類名疯特,通過簡單工廠模式可以在一定程度減少使用者的記憶量。
簡單工廠模式的主要缺點如下:
- 由于工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯肛走,職責過重漓雅, 一旦不能正常工作,整個系統(tǒng)都會受到影響朽色。
- 使用簡單工廣模式勢必會增加系統(tǒng)中類的個數(shù)(引入了新的工廠類)邻吞,增加了系統(tǒng)的復(fù)雜度和理解難度。
- 系統(tǒng)擴展困難葫男, 一旦添加新產(chǎn)品就不得不修改工廠邏輯抱冷,在產(chǎn)品類型較多時,有可能造成工廠邏輯過于復(fù)雜梢褐,不利于系統(tǒng)的擴展和維護旺遮。
- 簡單工廠模式由于使用了靜態(tài)工廠方法赵讯,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)。
工廠方法模式
在簡單工廠模式中只提供一個工廠類耿眉,它需要知道每一個產(chǎn)品對象的創(chuàng)建細節(jié)瘦癌,并決定何時實例化哪一個產(chǎn)品類。簡單工廠模式最大的缺點是當有新產(chǎn)品要加入到系統(tǒng)中時跷敬,必須修改工廠類讯私,需要在其中加入必要的業(yè)務(wù)邏輯,這違背了“開閉原則” 西傀。此外斤寇,在簡單工廠模式中,所有的產(chǎn)品都由同一個工廠創(chuàng)建拥褂,工廠類職責較重娘锁,業(yè)務(wù)邏輯較為復(fù)雜,具體產(chǎn)品與工廠類之間的耦合度高饺鹃,嚴重影響了系統(tǒng)的靈活性和擴展性莫秆,而工廠方法模式則可以很好地解決這一問題。
在工廠方法模式中悔详,不再提供一個統(tǒng)一的工廠類來創(chuàng)建所有的產(chǎn)品對象镊屎,而是針對不同的產(chǎn)品提供不同的工廠,系統(tǒng)提供一個與產(chǎn)品等級結(jié)構(gòu)對應(yīng)的工廠等級結(jié)構(gòu)茄螃。
工廠方法模式的定義:工廠方法模式(Factory Method Pattern)用來定義一個用于創(chuàng)建對象的接口缝驳,讓子類決定將哪一個類實例化。工廠方法模式讓一個類的實例化延遲到其子類归苍。工廠方法模式又簡稱為工廠模式( Factory Pattern )用狱,還可稱作虛擬構(gòu)造器模式( Virtual Constructor Pattern )或多態(tài)工廠模式( Polymorphic Factory Pattern )。工廠方法模式是一種類創(chuàng)建型模式拼弃。
工廠方法模式提供一個抽象工廠接口來聲明抽象工廠方法夏伊,而由其子類來具體實現(xiàn)工廠方法,創(chuàng)建具體的產(chǎn)品對象吻氧。工廠方法模式結(jié)構(gòu)如下所示溺忧。
在工廠方法模式結(jié)構(gòu)圖中包含如下幾個角色。
- Product(抽象產(chǎn)品類):它是定義產(chǎn)品的接口医男,是工廠方法模式所創(chuàng)建對象的超類型砸狞,也就是產(chǎn)品對象的公共父類捻勉。
- ConcreteProduct(具體產(chǎn)品類) : 它實現(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)品類的實例。
下面來看一個汽車與工廠實例朽寞。
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)品類,并且實現(xiàn)Vehicle 類的run 方法肘迎。每一種具體產(chǎn)品類都有一一對應(yīng)的工廠類CarFactory 甥温、BusFactory 、BicycleFactory 等妓布,所有的工廠都有共同的抽象父類Factory姻蚓。汽車與工廠具體的類結(jié)構(gòu)如下圖所示。
與簡單工廠模式相比匣沼, 工廠方法模式最重要的區(qū)別是引入了抽象工廠角色史简,抽象工廠可以是接口,也可以是抽象類或者具體類肛著。在抽象工廠中聲明了工廠方法但并未實現(xiàn)工廠方法圆兵, 具體產(chǎn)品對象的創(chuàng)建由其子類負責, 客戶端針對抽象工廠編程枢贿,可在運行時再指定具體工廠類殉农,具體工廠類實現(xiàn)了工廠方法, 不同的具體工廠可以創(chuàng)建不同的具體產(chǎn)品局荚。