工廠模式:一個(gè)即可簡單實(shí)現(xiàn),又可復(fù)雜實(shí)現(xiàn)的模式

點(diǎn)擊上方「藍(lán)字」關(guān)注我們

工廠模式的實(shí)現(xiàn)主要分為三種,分別是簡單工廠模式(Simple Factory)、工廠方法模式(Factory Method)和抽象工廠模式(Abastract Factory?);但是簡單工廠模式不屬于23種GOF設(shè)計(jì)模式之一。工廠模式在各種開源框架里使用非常普遍,例如Spring框架大量使用工程模式。下面分別介紹一下這三種實(shí)現(xiàn)。
0x01:??簡單工廠模式
簡單工廠模式也被稱為靜態(tài)工廠模式;簡單工廠模式可以將產(chǎn)品的使用和生產(chǎn)完全分開,客戶端只需要知道需要什么產(chǎn)品,如何來使用產(chǎn)品就可以了,而具體的產(chǎn)品生產(chǎn)任務(wù)由具體的工廠類來實(shí)現(xiàn)。工廠類根據(jù)傳進(jìn)來的參數(shù)生產(chǎn)具體的產(chǎn)品供消費(fèi)者使用。這種模式使得更加利于擴(kuò)展,當(dāng)有新的產(chǎn)品加入時(shí)僅僅需要在工廠中加入新產(chǎn)品的構(gòu)造就可以了。類圖如下

簡單工廠模式的實(shí)質(zhì)是由一個(gè)工廠類根據(jù)傳入的參數(shù),動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類(這些產(chǎn)品類繼承自一個(gè)父類或接口)的實(shí)例。該模式中包含的角色及其職責(zé):
工廠(Creator)角色:簡單工廠模式的核心,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯。工廠類的創(chuàng)建產(chǎn)品類的方法可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對(duì)象。
抽象產(chǎn)品(IProduct)角色:簡單工廠模式所創(chuàng)建的所有對(duì)象的父類,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
具體產(chǎn)品(Concrete Product)角色:是簡單工廠模式的創(chuàng)建目標(biāo),所有創(chuàng)建的對(duì)象都是充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。
抽象產(chǎn)品(IProduct)角色
public?interface?IFruit?{
????/**
?????*?種植水果方法
?????*/
????void?plant();
}
抽象產(chǎn)品(IProduct)角色
//實(shí)現(xiàn)種植蘋果
public?class?Apple?implements?IFruit?{
????public?void?plant()?{
????????System.out.println("種植蘋果");
????}
}
//實(shí)現(xiàn)種植橙子
public?class?Orange?implements?IFruit?{
????public?void?plant()?{
????????System.out.println("種植橙子");
????}
}
具體產(chǎn)品(Concrete Product)角色
public?class?PlantFruitsFactory?{
????public static?IFruit?plantFruit(String?fruitType)?{
????????//這里使用的if判斷,用switch一樣的道理
????????if?("Apple".equals(fruitType)){
????????????return?new?Apple();
????????}else?if?("Orange".equals(fruitType)){
????????????return?new?Orange();
????????}else?{
????????????return?null;
????????}
????}
}
測試用例
public?class?ClientCmd{
????public?static?void?main(String[]?args)?{
????????IFruit?fruit?=?PlantFruitsFactory.plantFruit("Apple");
????????fruit.plant();
????????fruit?=?PlantFruitsFactory.plantFruit("Orange");
????????fruit.plant();
????}
}
0x02:?工廠方法模式
工廠方法(Factory Method)模式的定義是一個(gè)創(chuàng)建產(chǎn)品對(duì)象的工廠接口,將實(shí)際創(chuàng)建工作推遲到子類當(dāng)中。核心工廠類不再負(fù)責(zé)產(chǎn)品的創(chuàng)建,這樣核心類成為一個(gè)抽象工廠角色,僅是負(fù)責(zé)具體工廠子類必須實(shí)現(xiàn)的接口,這樣進(jìn)一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品。類圖如下:

抽象工廠(Creator)角色:是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口。
具體工廠(Concrete Creator)角色:這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對(duì)象。
抽象產(chǎn)品(Product)角色:工廠方法模式所創(chuàng)建的對(duì)象的超類型,也就是產(chǎn)品對(duì)象的共同父類或共同擁有的接口。
具體產(chǎn)品(Concrete Product)角色:該角色實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對(duì)應(yīng)。
抽象產(chǎn)品(Product)角色
//抽象產(chǎn)品類
public?abstract?class?IMessage{
????//抽象產(chǎn)品方法
????public?void?send();
}
具體產(chǎn)品(Concrete Product)角色
//繼承抽象類實(shí)現(xiàn)產(chǎn)品EmailMessage類
public?class?EmailMessage extends?IMessage{
????//實(shí)現(xiàn)抽象產(chǎn)品方法
????@Overide
????public?void send(){
????????System.out.println("send Email Message~~");
????}
}
//繼承抽象類實(shí)現(xiàn)產(chǎn)品SmsMessage類
public?class?SmsMessage extends?IMessage{
????//實(shí)現(xiàn)抽象產(chǎn)品方法
????@Overide
????public?void send(){
????????System.out.println("send Sms Message ~~~ ");
????}
}
抽象工廠(Creator)角色
//工廠抽象類
public?abstract?class?Factory?{
????//抽象工廠方法
????public?abstract?IMessage createMessage();
}
具體工廠(Concrete?Creator)角色
//具體工廠類EmailMessageFactory
public?class?EmailMessageFactory?extends?Factory?{
????@Overide
????public?IMessage createMessage()?{
????????System.out.println("生產(chǎn)了一個(gè)EmailMessage ");
????????return?new?EmailMessage();
????}
}
//具體工廠類SmsMessageFactory
public?class?SmsMessageFactory?extends?Factory?{
????@Overide
????public?IMessage createMessage()?{
????????System.out.println("生產(chǎn)了一個(gè)SmsMessage");
????????return?new?SmsMessage();
????}
}
測試用例
//調(diào)用方代碼
public?class?ClientCmd?{
????public?static?void?main(String[]?args)?{
????????//產(chǎn)生一個(gè)Email工廠
????????Factory?factory?=?new?EmailMessageFactory();
????????factory?.createMessage().send();
????????//產(chǎn)生一個(gè)短信工廠
????????factory?=?new?SmsMessageFactory();
????????orangeFactory.createMessage().send();
????}
}
0x03:?抽象工廠模式
抽象工廠模式相對(duì)于工廠方法模式來說,就是工廠方法模式是針對(duì)一個(gè)產(chǎn)品系列的,而抽象工廠模式是針對(duì)多個(gè)產(chǎn)品系列的,即工廠方法模式是一個(gè)產(chǎn)品系列一個(gè)工廠類,而抽象工廠模式是多個(gè)產(chǎn)品系列一個(gè)工廠類。在抽象工廠模式中,客戶端不再負(fù)責(zé)對(duì)象的創(chuàng)建,而是把這個(gè)責(zé)任丟給了具體的工廠類,客戶端只負(fù)責(zé)對(duì)對(duì)象的調(diào)用,從而明確了各個(gè)類的職責(zé)。并且當(dāng)一系列相互關(guān)聯(lián)的產(chǎn)品被設(shè)計(jì)到一個(gè)工廠類里后,客戶端的調(diào)用將會(huì)變得非常簡單,而且如果要更換這一系列的產(chǎn)品,則只需要更換一個(gè)工廠類即可。類圖如下

抽象工廠模式中存在四種角色,分別是抽象工廠角色,具體工廠角色,抽象產(chǎn)品角色,具體產(chǎn)品角色。?
抽象工廠角色:擔(dān)任這個(gè)角色的是工廠方法模式的核心,它是與應(yīng)用系統(tǒng)商業(yè)邏輯無關(guān)的。
具體工廠角色:這個(gè)角色直接在客戶端的調(diào)用下創(chuàng)建產(chǎn)品的實(shí)例。這個(gè)角色含有選擇合適的產(chǎn)品對(duì)象的邏輯,而這個(gè)邏輯是與應(yīng)用系統(tǒng)的商業(yè)邏輯緊密相關(guān)的。?
抽象產(chǎn)品角色:擔(dān)任這個(gè)角色的類是工廠方法模式所創(chuàng)建的對(duì)象的父類,或它們共同擁有的接口。
具體產(chǎn)品角色:抽象工廠模式所創(chuàng)建的任何產(chǎn)品對(duì)象都是某一個(gè)具體產(chǎn)品類的實(shí)例。這是客戶端最終需要的東西,其內(nèi)部充滿了應(yīng)用系統(tǒng)的商業(yè)邏輯。
抽象產(chǎn)品角色
//抽象形狀類
public?abstract?class?Shape?{
????public?abstract?void?sayShape();
}
//抽象顏色類
public?abstract?class?Color?{
????public?abstract?void?sayColor();
}
具體產(chǎn)品角色
//矩形類
public?class?Retangle?extends?Shape?{
????@Overide
????public?void?sayShape()?{
????????System.out.println("Hi,?I'm?Retangle!");
????}
}
//圓形類
public?class?Circle?extends?Shape?{
????@Overide
????public?void?sayShape()?{
????????System.out.println("Hi,?I'm?Circle!");
????}
}
//紅色類
public?class?Red?extends?Color?{
????@Overide
????public?void?sayColor()?{
????????System.out.println("Hi,?I'm?Red!");
????}
}
//白色類
public?class?White?extends?Color?{
????@Overide
????public?void?sayColor()?{
????????System.out.println("Hi,?I'm?White!");
????}
}
抽象工廠角色
//抽象工廠類
public?abstract?class?ShapeFactory?{
????public?abstract?Shape?createShape();
????public?abstract?Color?createColor();
}
具體工廠角色
//紅色的圓
public?class?RedCircleFactory?extends?ShapeFactory?{
????@Overide
????public?Shape?createShape()?{
????????return?new?Circle();
????}
????@Overide
????public?Color?createColor()?{
????????return?new?Red();
????}
}
//白色的圓
public?class?WhiteCircleFactory?extends?ShapeFactory?{
????@Overide
????public?Shape?createShape()?{
????????return?new?Circle();
????}
????@Overide
????public?Color?createColor()?{
????????return?new?White();
????}
}
測試用例?
public?class?ClientCmd?{??
????public?static?void?main(String[]?args){??
//紅色的圓
????????ShapeFactory?factory?=?new?RedCircleFactory();??
????????factory.createShape().sayShape();??
????????factory.createColor().sayShapeColor();??
//白色的圓
????????ShapeFactory?factory?=?new?WhiteCircleFactory();??
????????factory.createShape().sayShape();??
????????factory.createColor().sayShapeColor();??
????}??
}?
掃碼二維碼
獲取更多精彩
Java樂園

