蘋果暫停在俄羅斯投放 App Store 廣告,並已停售產品
介紹:
工廠模式專門負責及那個大量有共同介面的類例項化,工廠模式可以動態決定獎哪一個類例項化,不必事先知道每次要例項化哪一個類。工廠模式有一下幾種形態:
- 簡單工廠模式:又稱靜態工廠方法模式,是不同的工廠方法模式的一個特殊實現。
- 工廠方法模式:又稱多型性工廠模式
- 抽象工廠模式:又稱工具箱模式
簡單工廠模式:
比如說有一個農場公司,專門向市場銷售以下水果:葡萄(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類實現這個角色