工廠模式

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();
	}
}

 運行結果:

恭喜您獲得新英雄:露娜!
釋放技能:新月突擊!
紫霞仙子皮膚特效!
恭喜您獲得新英雄:凱!
釋放技能:不滅魔軀!
青龍志皮膚特效!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章