介紹:
工廠模式專門負責及那個大量有共同介面的類實體化,工廠模式可以動態決定獎哪一個類實體化,不必事先知道每次要實體化哪一個類,工廠模式有一下幾種形態:
- 簡單工廠模式:又稱靜態工廠方法模式,是不同的工廠方法模式的一個特殊實作,
- 工廠方法模式:又稱多型性工廠模式
- 抽象工廠模式:又稱工具箱模式
簡單工廠模式:
比如說有一個農場公司,專門向市場銷售以下水果:葡萄(Grape)、草莓(Strawberry)、蘋果(Apple),
水果介面規定出所有的水果必須實作的介面:種植plant()、生長grow()、識訓harvest().
其UML類圖如下:

那么水果介面的代碼如下:
package com.charon.factory.simpleFactory;
/**
* @className: Fruit
* @description: 水果介面
* @author: charon
* @create: 2022-03-06 20:30
*/
public interface Fruit {
/**
* 種植
*/
void plant();
/**
* 生長
*/
void grow();
/**
* 識訓
*/
void harvest();
}
草莓類是水果類的一種,因此他實作了水果介面中所有宣告的方法,
package com.charon.factory.simpleFactory;
/**
* @className: Strawberry
* @description:
* @author: charon
* @create: 2022-03-06 20:43
*/
public class Strawberry implements Fruit{
@Override
public void plant() {
System.out.println("草莓種植了,,,,");
}
@Override
public void grow() {
System.out.println("草莓生長中,,,,");
}
@Override
public void harvest() {
System.out.println("草莓識訓了,,,,");
}
}
蘋果類也是水果類的一種,因此他實作了水果介面中所有宣告的方法:
package com.charon.factory.simpleFactory;
/**
* @className: Apple
* @description:
* @author: charon
* @create: 2022-03-06 20:36
*/
public class Apple implements Fruit{
@Override
public void plant() {
System.out.println("蘋果樹種植了,,,,");
}
@Override
public void grow() {
System.out.println("蘋果樹生長中,,,,");
}
@Override
public void harvest() {
System.out.println("蘋果樹識訓了,,,,");
}
}
葡萄類也是水果類的一種,因此他實作了水果介面中所有宣告的方法:
package com.charon.factory.simpleFactory;
/**
* @className: Grape
* @description:
* @author: charon
* @create: 2022-03-06 20:41
*/
public class Grape implements Fruit{
@Override
public void plant() {
System.out.println("葡萄種植了,,,,");
}
@Override
public void grow() {
System.out.println("葡萄生長中,,,,");
}
@Override
public void harvest() {
System.out.println("葡萄識訓了,,,,");
}
}
FruitGardener類是園丁類,會根據客戶端的要求,創建出不同的水果物件,所有的創建物件的任務都由這個類完成,
package com.charon.factory.simpleFactory;
/**
* @className: FruitGardener
* @description: 園丁類
* @author: charon
* @create: 2022-03-06 20:46
*/
public class FruitGardener {
/**
* 靜態工廠方法
*
* @param fruitType 水果型別
* @return
*/
public static Fruit factory(String fruitType) {
if ("apple".equalsIgnoreCase(fruitType)) {
return new Apple();
} else if ("Grape".equalsIgnoreCase(fruitType)) {
return new Grape();
} else if ("Strawberry".equalsIgnoreCase(fruitType)) {
return new Strawberry();
}
return null;
}
}
測驗:
package com.charon.factory.simpleFactory;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-06 20:50
*/
public class Test {
public static void main(String[] args) {
Fruit apple = FruitGardener.factory("apple");
apple.plant();
apple.grow();
apple.harvest();
Fruit grape = FruitGardener.factory("grape");
grape.plant();
grape.grow();
grape.harvest();
Fruit strawberry = FruitGardener.factory("strawberry");
strawberry.plant();
strawberry.grow();
strawberry.harvest();
}
}
列印結果:
蘋果樹種植了,,,,
蘋果樹生長中,,,,
蘋果樹識訓了,,,,
葡萄種植了,,,,
葡萄生長中,,,,
葡萄識訓了,,,,
草莓種植了,,,,
草莓生長中,,,,
草莓識訓了,,,,
簡單工廠模式就是由一個工廠類根據傳入的引數決定創建出哪一種產品的類的實體,
這種模式的優點:好理解,簡單易操作,
這種模式的缺點:違反了設計模式的ocp原則,即對擴展開放,對修改關閉,
如果我們需要新添加一種水果,那么需要新添加一個水果類,還需要在FruitGardener中添加這種水果的實體化,同時,由于使用的靜態方法作為的工廠方法,而靜態方法無法由子類繼承,因此,工廠角色無法形成基于繼承的等級結構,
從上面可以知道,簡單工廠模式涉及到工廠角色、抽象產品角色以及具體產品角色:
- 工廠角色:擔任這個角色的是工廠方法模式的核心,含有與應用緊密相關的商業邏輯,工廠類在客戶端的直接呼叫下創建產品物件,往往由一個具體的java類實作
- 抽象產品角色:擔任這個角色的類是由工廠方法模式所創建的物件的父類,或他們共同擁有的介面,抽象產品角色可以用一個java介面或者java抽象類實作
- 具體產品角色:工廠方法模式所創建的任何物件都是這個角色的實體,具體產品角色由一個個具體的java類實作
工廠方法模式:
工廠方法模式是簡單工廠模式的進一步抽象和推廣,由于使用了多型性,工廠方法模式保持了簡單工廠模式的優點,也克服了他的缺點,在工廠方法模式中,核心的工廠類不再負責所有的產品的創建,而是將具體創建的作業交給子類去做,這個核心類則成為了一個抽象工廠角色,僅負責給出具體工廠子類必須實作的介面,而不是接觸哪一個產品類應當被實體化這種細節,
還是上面的例子,由于農場規模擴大,一個園丁已經處理不過來了,所以現在每一種水果都需要專門的園丁來管理了,那么上面的FruitGardener這個全能角色就成了抽象的園丁角色,這個角色規定出具體園丁角色需要實作的具體職能,而真正負責水果管理的則是具體的園丁角色,
本系統的UML類圖如下:

FruitGardener介面類:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: FruitGardener
* @description: 園丁類
* @author: charon
* @create: 2022-03-06 20:46
*/
public interface FruitGardener {
/**
* 靜態工廠方法
*
* @param fruitType 水果型別
* @return
*/
Fruit factory();
}
AppleGardener類是具體工廠類,它實作了FruitGardener 介面,提供了工廠方法的實作:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Apple;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: AppleGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class AppleGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Apple();
}
}
GrapeGardener類是具體工廠類,它實作了FruitGardener 介面,提供了工廠方法的實作:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
import com.charon.factory.simpleFactory.Grape;
/**
* @className: GrapeGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class GrapeGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Grape();
}
}
StrawberryGardener類是具體工廠類,它實作了FruitGardener 介面,提供了工廠方法的實作:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
import com.charon.factory.simpleFactory.Strawberry;
/**
* @className: StrawberryGardener
* @description:
* @author: charon
* @create: 2022-03-06 23:04
*/
public class StrawberryGardener implements FruitGardener{
@Override
public Fruit factory() {
return new Strawberry();
}
}
Test類:
package com.charon.factory.factoryMethod;
import com.charon.factory.simpleFactory.Fruit;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-06 23:11
*/
public class Test {
public static void main(String[] args) {
FruitGardener appleGardener = new AppleGardener();
Fruit apple = appleGardener.factory();
apple.plant();
apple.plant();
apple.harvest();
FruitGardener grapeGardener = new GrapeGardener();
Fruit grape = grapeGardener.factory();
grape.plant();
grape.plant();
grape.harvest();
FruitGardener strawberryGardener = new StrawberryGardener();
Fruit strawberry = strawberryGardener.factory();
strawberry.plant();
strawberry.plant();
strawberry.harvest();
}
}
列印結果:
蘋果樹種植了,,,,
蘋果樹生長中,,,,
蘋果樹識訓了,,,,
葡萄種植了,,,,
葡萄生長中,,,,
葡萄識訓了,,,,
草莓種植了,,,,
草莓生長中,,,,
草莓識訓了,,,,
從上面可以知道,工廠方法模式涉及到抽象工廠角色、具體工廠角色、抽象產品角色以及具體產品角色:
- 抽象工廠角色:擔任這個角色的是工廠方法模式的核心,它是與應用程式無關的,任何在模式中創建物件的工廠類必須實作這個介面,這個角色也常常使用抽象Java類實作,
- 具體工廠角色:擔任這個角色的是實作了抽象工廠介面的具體Java類,具體工廠角色含有與應用密切相關的邏輯,并且受到應用程式的呼叫以創建產品物件,
- 抽象產品角色:工廠方法模式所創建的物件的超型別,也就是產品物件的共同父類或共同擁有的介面,這個角色也常常使用抽象Java類實作,
- 具體產品角色:這個角色實作了抽象產品角色所宣告的介面,工廠方法模式所創建的每一個物件都是某個具體產品角色的實體,
抽象工廠模式:
抽象工廠模式可以向客戶端提供一個介面,使得客戶端在不必指定產品的具體型別的情況下,創建多個產品族中的產品物件,這就是抽象工廠模式的用意,
為了方便引進抽象工廠模式,特地引進了一個新的概念:產品族,是指與不同產品等級結構中功能相關聯的產品組成的家族,
還是上面的例子,隨著市場的擴大,農場公司再次面臨新的發展,引入了蔬菜大棚技術,在大棚內種植熱帶和亞熱帶的水果和蔬菜,
因此在這個系統里,產品分成兩個等級結構:水果(熱帶水果,亞熱帶水果)和蔬菜(熱帶蔬菜,亞熱帶蔬菜),園丁呢,也分成兩類:管理熱帶水果蔬菜的園丁(tropicGardener)和管理亞熱帶水果蔬菜的園丁(subtropicalGardener),
本系統的UML類圖如下:

Fruit 水果介面類:
package com.charon.factory.absFactory;
/**
* @className: Fruit
* @description: 水果類
* @author: charon
* @create: 2022-03-08 22:12
*/
public interface Fruit {
}
TropicFruit 熱帶水果實作類:
package com.charon.factory.absFactory;
/**
* @className: TropicFruit
* @description: 熱帶水果
* @author: charon
* @create: 2022-03-08 22:13
*/
public class TropicFruit implements Fruit{
private String name;
public TropicFruit(String name) {
this.name = name;
System.out.println("熱帶水果: "+ name);
}
}
SubtropicFruit 亞熱帶水果實作類:
package com.charon.factory.absFactory;
/**
* @className: TropicFruit
* @description: 亞熱帶水果
* @author: charon
* @create: 2022-03-08 22:13
*/
public class SubtropicFruit implements Fruit{
private String name;
public SubtropicFruit(String name) {
this.name = name;
System.out.println("亞熱帶水果: "+ name);
}
}
Veggie 蔬菜類介面:
package com.charon.factory.absFactory;
/**
* @className: Veggie
* @description: 蔬菜類
* @author: charon
* @create: 2022-03-08 22:12
*/
public interface Veggie {
}
TropicVeggie 熱帶蔬菜:
package com.charon.factory.absFactory;
/**
* @className: TropicVeggie
* @description: 熱帶蔬菜
* @author: charon
* @create: 2022-03-08 22:13
*/
public class TropicVeggie implements Veggie{
private String name;
public TropicVeggie(String name) {
this.name = name;
System.out.println("熱帶蔬菜: "+ name);
}
}
SubtropicVeggie 亞熱帶蔬菜:
package com.charon.factory.absFactory;
/**
* @className: TropicVeggie
* @description: 熱帶蔬菜
* @author: charon
* @create: 2022-03-08 22:13
*/
public class SubtropicVeggie implements Veggie{
private String name;
public SubtropicVeggie(String name) {
this.name = name;
System.out.println("亞熱帶蔬菜: "+ name);
}
}
Gardener 園丁介面類:
package com.charon.factory.absFactory;
/**
* @className: Gardener
* @description: 園丁的頂級介面
* @author: charon
* @create: 2022-03-08 22:09
*/
public interface Gardener {
/**
* 創建亞熱帶水果
* @return
*/
Fruit createFruit();
/**
* 創建亞熱帶蔬菜
* @return
*/
Veggie createVeggie();
}
TropicGardener 熱帶園丁類:
package com.charon.factory.absFactory;
/**
* @className: TropicGardener
* @description: 管理熱帶水果蔬菜的園丁類
* @author: charon
* @create: 2022-03-08 22:10
*/
public class TropicGardener implements Gardener{
/**
* 創建熱帶水果
* @return
*/
@Override
public Fruit createFruit(){
return new TropicFruit("蘋果");
}
/**
* 創建熱帶蔬菜
* @return
*/
@Override
public Veggie createVeggie(){
return new TropicVeggie("白菜");
}
}
SubtropicGardener 亞熱帶園丁類:
package com.charon.factory.absFactory;
import java.util.concurrent.Future;
/**
* @className: SubtropicGardener
* @description: 管理亞熱帶水果蔬菜的園丁類
* @author: charon
* @create: 2022-03-08 22:11
*/
public class SubtropicGardener implements Gardener{
/**
* 創建亞熱帶水果
* @return
*/
@Override
public Fruit createFruit(){
return new SubtropicFruit("蘋果");
}
/**
* 創建亞熱帶蔬菜
* @return
*/
@Override
public Veggie createVeggie(){
return new SubtropicVeggie("白菜");
}
}
test 測驗類:
package com.charon.factory.absFactory;
/**
* @className: Test
* @description:
* @author: charon
* @create: 2022-03-08 22:23
*/
public class Test {
public static void main(String[] args) {
Gardener tropicGardener = new TropicGardener();
tropicGardener.createFruit();
tropicGardener.createVeggie();
Gardener subtropicGardener = new SubtropicGardener();
subtropicGardener.createFruit();
subtropicGardener.createVeggie();
}
}
抽象工廠模式涉及到一下的角色:
- 抽象工廠角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統的商業邏輯無關的,通常是使用java介面或者抽象java類實作,而所有的具體工廠類必須實作這個java介面或繼承這個抽象java類
- 具體工廠類角色:這個角色直接在客戶端的呼叫下創建產品的實體,這個角色含有選擇的產品物件的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的,通常使用具體java類實作的這個角色
- 抽象產品角色:擔任這個角色的類是工廠方法模式所創建的物件的父類,或他們共同擁有的介面,通常使用java介面或者抽象java類實作這一角色
- 具體產品角色:抽象工廠模式所創建的任何產品物件都是某一個具體產品類的實體,這事客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯,通常使用具體的java類實作這個角色
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/440533.html
標籤:設計模式
上一篇:設計模式學習記錄
下一篇:設計模式學習記錄
