GoF中對於工廠模式的定義:
“Define an interface for creating an object, but let subclasses decide which class to instantiate.
Factory Method lets a class defer instantiation to subclasses.”
(在基類中定義創建對象的一個接口,讓子類決定實例化哪個類。工廠方法讓一個類的實例化延遲到子類中進行。)
使用工廠的場景:
(1)Spring中通過getBean("xxx")獲取Bean;
(2) Java消息服務JMS中(下面以消息隊列ActiveMQ爲例子)
(3)JDBC是一種用於執行SQL語句的java API,可以爲多種關係數據庫提供統一訪問,它由一組用java語言編寫的類和接口組成。
>簡單工廠
嚴格來說,簡單工廠並不是23種設計模式之一,它較爲簡單,適用於創建對象不多的情況。
但是簡單工廠違背了“開放-封閉原則”(面向拓展開放,面向修改關閉)。
工廠用來管理對象(產品)的創建,使用不同的標籤(ID)來區分要要創建的對象(生產的產品)。
簡單工程模式角色分配:
- 工廠(Factory)角色 :簡單工廠模式的核心,它負責實現創建所有實例的內部邏輯。工廠類可以被外界直接調用,創建所需的產品對象。
- 抽象產品(Product)角色 :簡單工廠模式所創建的所有對象的父類,它負責描述所有實例所共有的公共接口。
- 具體產品(Concrete Product)角色:簡單工廠模式的創建目標,所有創建的對象都是充當這個角色的某個具體類的實例
代碼舉例:
抽象產品角色
public interface Hero {
//購買英雄
public void buyHero();
//使用英雄技能
public void useSkill();
}
具體產品角色
public class Luna implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:露娜!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:新月突擊!");
}
}
public class Kai implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:凱!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:不滅魔軀!");
}
}
工廠角色
public class HeroFactory {
public static Hero getHero(String HeroType) {
if ("luna".equalsIgnoreCase(HeroType)) {
return new Luna();
} else if ("kai".equalsIgnoreCase(HeroType)) {
return new Kai();
}
return null;
}
public static void main(String[] args) {
Hero kai=HeroFactory.getHero("kai");
kai.buyHero();
kai.useSkill();
Hero luna=HeroFactory.getHero("luna");
luna.buyHero();
luna.useSkill();
}
}
運行:
恭喜您獲得新英雄:凱!
釋放技能:不滅魔軀!
恭喜您獲得新英雄:露娜!
釋放技能:新月突擊!
>工廠方法模式
工廠方法模式是一般項目中使用最多的工廠模式。
在工廠方法模式中,我們不再提供一個統一的工廠類來創建所有的對象,而是針對不同的對象提供不同的工廠。
也就是說 每個對象都有一個與之對應的工廠 。
工廠方法模式角色分配:
- 抽象工廠(Abstract Factory)角色:是工廠方法模式的核心,與應用程序無關。任何在模式中創建的對象的工廠類必須實現這個接口。
- 具體工廠(Concrete Factory)角色 :這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,並且受到應用程序調用以創建某一種產品對象。
- 抽象產品(AbstractProduct)角色 :工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。
- 具體產品(Concrete Product)角色 :這個角色實現了抽象產品角色所定義的接口。某具體產品有專門的具體工廠創建,它們之間往往一一對應。
代碼舉例:
抽象產品角色
public interface Hero {
//購買英雄
public void buyHero();
//使用英雄技能
public void useSkill();
}
具體產品角色
public class Luna implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:露娜!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:新月突擊!");
}
}
public class Kai implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:凱!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:不滅魔軀!");
}
}
抽象工廠角色
public interface HeroFactories {
public Hero getHero();
}
具體工廠角色
public class LunaFactory implements HeroFactories{
@Override
public Hero getHero() {
return new Luna();
}
}
public class KaiFactory implements HeroFactories {
@Override
public Hero getHero() {
return new Kai();
}
}
測試類
public class Run {
public static void main(String[] args) {
HeroFactories lunaFactory=new LunaFactory();
Hero luna=lunaFactory.getHero();
luna.buyHero();
luna.useSkill();
HeroFactories kaiFactory=new KaiFactory();
Hero kai = kaiFactory.getHero();
kai.buyHero();
kai.useSkill();
}
}
運行結果:
恭喜您獲得新英雄:露娜!
釋放技能:新月突擊!
恭喜您獲得新英雄:凱!
釋放技能:不滅魔軀!
>抽象工廠模式(工廠裏有多個生產產品(對象)的方法,這些產品屬於同一產品族)
抽象工廠模式是最難理解的一種。
在工廠方法模式中,其實我們有一個潛在意識的意識。那就是我們生產的都是同一類產品。抽象工廠模式是工廠方法的僅一步深化,在這個模式中的工廠類不單單可以創建一種產品,而是可以創建一組產品。
適用場景:
- 和工廠方法一樣客戶端不需要知道它所創建的對象的類。
- 需要一組對象共同完成某種功能時,並且可能存在多組對象完成不同功能的情況。(同屬於同一個產品族的產品)
- 系統結構穩定,不會頻繁的增加對象。(因爲一旦增加就需要修改原有代碼,不符合開閉原則)
抽象工廠角色分配:
- 抽象工廠(AbstractFactory)角色 :是工廠方法模式的核心,與應用程序無關。任何在模式中創建的對象的工廠類必須實現這個接口。
- 具體工廠類(ConreteFactory)角色 :這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,並且受到應用程序調用以創建某一種產品對象。
- 抽象產品(Abstract Product)角色 :工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。
- 具體產品(Concrete Product)角色 :抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。在抽象工廠中創建的產品屬於同一產品族,這不同於工廠模式中的工廠只創建單一產品。
與工廠方法模式區別:
抽象工廠是生產一整套有產品的(至少要生產兩個產品),這些產品必須相互是有關係或有依賴的,而工廠方法中的工廠是生產單一產品的工廠。
代碼舉例:
抽象產品角色(不止一個,而是一個系列)
public interface Hero {
//購買英雄
public void buyHero();
//使用英雄技能
public void useSkill();
}
public interface GameSkin {
//皮膚展示
public void show();
}
具體產品角色
public class Kai implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:凱!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:不滅魔軀!");
}
}
public class Luna implements Hero {
@Override
public void buyHero() {
System.out.println("恭喜您獲得新英雄:露娜!");
}
@Override
public void useSkill() {
System.out.println("釋放技能:新月突擊!");
}
}
public class KaiSkin implements GameSkin {
@Override
public void show() {
System.out.println("青龍志皮膚特效!");
}
}
public class LunaSkin implements GameSkin{
@Override
public void show() {
System.out.println("紫霞仙子皮膚特效!");
}
}
抽象工廠角色
public interface HeroFactories {
public Hero getHero();
public GameSkin getSkin();
}
具體工廠角色
public class KaiFactory implements HeroFactories {
@Override
public Hero getHero() {
return new Kai();
}
@Override
public GameSkin getSkin() {
return new KaiSkin();
}
}
public class LunaFactory implements HeroFactories{
@Override
public Hero getHero() {
return new Luna();
}
@Override
public GameSkin getSkin() {
return new LunaSkin();
}
}
測試類:
public class Run {
public static void main(String[] args) {
HeroFactories lunaFactory=new LunaFactory();
Hero luna=lunaFactory.getHero();
luna.buyHero();
luna.useSkill();
GameSkin lunaSkin=lunaFactory.getSkin();
lunaSkin.show();
HeroFactories kaiFactory=new KaiFactory();
Hero kai = kaiFactory.getHero();
kai.buyHero();
kai.useSkill();
GameSkin kaiSkin=kaiFactory.getSkin();
kaiSkin.show();
}
}
運行結果:
恭喜您獲得新英雄:露娜!
釋放技能:新月突擊!
紫霞仙子皮膚特效!
恭喜您獲得新英雄:凱!
釋放技能:不滅魔軀!
青龍志皮膚特效!