設計模式 - 抽象工廠模式-依賴工廠模式

老闆:阿飛,上次麪包店老闆找我聊了一下,他們是大規模的從各大小原料商鋪進的原料,出現了好多偷工減料的情況,現在他們做大了,想自己開幾個原料提供點,如果中國的顧客去買,發現原料用盡,就要去找中國原料提供點,拿原料,這個功能看看好不好實現,如果好實現,你就開始做吧!

項目組長阿飛:這個可以實現,我去操作吧

項目組長阿飛:小三,來需求了…………,聽懂了嗎?你應該知道怎麼拓展代碼。

阿三:嗯嗯,我知道,我去拓展一下

三天過後。。

阿三:飛哥,設計好了,你看下。

這個是一個地址描述類,主要是表明是哪個地區的,有什麼不同,這個是可以拓展的

 1package com.abstractFactoryPattern.material.vo;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 材料所在地
 6 * @author: Mr.Yang
 7 * @create: 2018-11-20 21:24
 8 **/
 9public  class Address {
10    public String name=null;
11}

這個是中國地址類,對Address做了一個拓展,可以重寫父類方法或者賦值屬性,將特殊業務拿到子類去處理,做了個小拓展。

 1package com.abstractFactoryPattern.material.vo;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 代表了中國的材料源地址,將它與其他材料源實現一個共同的父類,方便接收與拓展
 6 * @author: Mr.Yang
 7 * @create: 2018-11-20 21:24
 8 **/
 9public class ChineseAddress extends Address{
10
11    public ChineseAddress(){
12        name="中國材料源";
13    }
14}

新加坡地址類,也是一樣的。

 1package com.abstractFactoryPattern.material.vo;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 代表了新加坡的材料源地址,將它與其他材料源實現一個共同的父類,方便接收與拓展
 6 * @author: Mr.Yang
 7 * @create: 2018-11-20 21:24
 8 **/
 9public class SignaporeAddress extends Address{
10
11    public SignaporeAddress(){
12        name="新加坡材料源";
13    }
14
15}

泰國的亦是如此

 1package com.abstractFactoryPattern.material.vo;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 代表了泰國的材料源地址,將它與其他材料源實現一個共同的父類,方便接收與拓展
 6 * @author: Mr.Yang
 7 * @create: 2018-11-20 21:25
 8 **/
 9public class ThailandAddress extends Address{
10
11    public ThailandAddress(){
12        name="泰國材料源";
13    }
14
15}

這是一個材料工程的一個接口類,各大地方具體材料必須實現這個接口類

 1package com.abstractFactoryPattern.material.factory;
 2
 3import com.abstractFactoryPattern.material.vo.Address;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 材料工程
 8 * @author: Mr.Yang
 9 * @create: 2018-11-20 20:58
10 **/
11public interface  MaterialFactory {
12    /**
13     * 創建材料方法
14     * @return
15     */
16     Address selectAddress();
17
18
19}

中國的原料工程,實現了材料工程的接口類,返回了一箇中國的地址類

 1package com.abstractFactoryPattern.material.factoryImpl;
 2
 3import com.abstractFactoryPattern.material.factory.MaterialFactory;
 4import com.abstractFactoryPattern.material.vo.Address;
 5import com.abstractFactoryPattern.material.vo.ChineseAddress;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 中國的原材料工程
10 * @author: Mr.Yang
11 * @create: 2018-11-20 21:10
12 **/
13public class ChineseMaterialFactory implements MaterialFactory {
14
15    @Override
16    public Address selectAddress() {
17        return new ChineseAddress();
18    }
19}

新加坡的原料工程,實現了材料工程的接口類,返回了一個新加坡的地址類

 1package com.abstractFactoryPattern.material.factoryImpl;
 2
 3import com.abstractFactoryPattern.material.factory.MaterialFactory;
 4import com.abstractFactoryPattern.material.vo.Address;
 5import com.abstractFactoryPattern.material.vo.SignaporeAddress;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 新加坡的原材料工程
10 * @author: Mr.Yang
11 * @create: 2018-11-20 21:11
12 **/
13public class SingaporeMaterialFactory implements MaterialFactory {
14    @Override
15    public Address selectAddress() {
16        return new SignaporeAddress();
17    }
18}

泰國的原料工程,實現了材料工程的接口類,返回了一個泰國的地址類

 1package com.abstractFactoryPattern.material.factoryImpl;
 2
 3import com.abstractFactoryPattern.material.factory.MaterialFactory;
 4import com.abstractFactoryPattern.material.vo.Address;
 5import com.abstractFactoryPattern.material.vo.ThailandAddress;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 泰國的原材料工程
10 * @author: Mr.Yang
11 * @create: 2018-11-20 21:12
12 **/
13public class ThailandMaterialFactory implements MaterialFactory {
14
15    @Override
16    public Address selectAddress() {
17        return new ThailandAddress();
18    }
19}

麪包店的抽象類,進行了微改動,接受了地址類,增加了,去選擇地址這個抽象方法,也就意味着,所有實現這個麪包工程的將要去實現這個方法

 1package com.abstractFactoryPattern.kind.factory;
 2
 3import com.abstractFactoryPattern.material.vo.Address;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 麪包口味的抽象類
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:24
10 **/
11public abstract class BreadFactory {
12    protected String name;
13    protected String type;
14
15    //新增地址類屬性
16    public Address address;
17
18    //新增抽象方法
19    protected abstract void toSelectAddress();
20
21    public BreadFactory stir(){
22        System.out.println("攪拌");
23        return this;
24    }
25
26    public BreadFactory rubbingRound(){
27        System.out.println("搓圓");
28        return this;
29    }
30
31    public BreadFactory machining(){
32        System.out.println("加工");
33        return this;
34    }
35    public BreadFactory bake(){
36        System.out.println("烘烤");
37        return this;
38    }
39
40    public String getName() {
41        return name;
42    }
43
44    public BreadFactory setName(String name) {
45        this.name = name;
46        return this;
47    }
48
49    public String getType() {
50        return type;
51    }
52
53    public BreadFactory setType(String type) {
54        this.type = type;
55        return this;
56    }
57}

中國蘋果口味的麪包,實現抽象方法,重新給父類的幾個屬性賦值

 1package com.abstractFactoryPattern.kind.factoryImpl;
 2
 3import com.abstractFactoryPattern.kind.factory.BreadFactory;
 4import com.abstractFactoryPattern.material.factory.MaterialFactory;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 中國蘋果口味麪包
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:48
11 **/
12public class ChinaAppleBread  extends BreadFactory {
13    MaterialFactory materialFactory;
14
15    //使用這個有參構造,去爲屬性賦值
16    public ChinaAppleBread(MaterialFactory materialFactory){
17        name="中國蘋果口味";
18        type="1";
19        this.materialFactory=materialFactory;
20        toSelectAddress();
21    }
22
23    @Override
24    protected void toSelectAddress() {
25        address = materialFactory.selectAddress();
26    }
27
28    //可以重寫父類方法,進行特殊處理
29}

中國奶油口味的麪包,實現抽象方法,重新給父類的幾個屬性賦值

 1package com.abstractFactoryPattern.kind.factoryImpl;
 2
 3import com.abstractFactoryPattern.kind.factory.BreadFactory;
 4import com.abstractFactoryPattern.material.factory.MaterialFactory;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 中國奶油口味麪包
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:48
11 **/
12public class ChinaCreamBread extends BreadFactory {
13    MaterialFactory materialFactory;
14
15    public ChinaCreamBread(MaterialFactory materialFactory){
16        this.materialFactory=materialFactory;
17        name="中國奶油口味";
18        type="2";
19        toSelectAddress();
20    }
21
22    @Override
23    protected void toSelectAddress() {
24        address = materialFactory.selectAddress();
25    }
26    //可以重寫父類方法,進行特殊處理
27}

新加坡蘋果口味的麪包,實現抽象方法,重新給父類的幾個屬性賦值

 1package com.abstractFactoryPattern.kind.factoryImpl;
 2
 3import com.abstractFactoryPattern.kind.factory.BreadFactory;
 4import com.abstractFactoryPattern.material.factory.MaterialFactory;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 新加坡蘋果口味麪包
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:50
11 **/
12public class SingaporeAppleBread extends BreadFactory {
13    MaterialFactory materialFactory;
14
15    public SingaporeAppleBread(MaterialFactory materialFactory){
16        this.materialFactory=materialFactory;
17        name="新加坡蘋果口味";
18        type="3";
19        toSelectAddress();
20    }
21
22    @Override
23    protected void toSelectAddress() {
24        address = materialFactory.selectAddress();
25    }
26    //可以重寫父類方法,進行特殊處理
27}

新加坡奶油口味的麪包,實現抽象方法,重新給父類的幾個屬性賦值

 1package com.abstractFactoryPattern.kind.factoryImpl;
 2
 3import com.abstractFactoryPattern.kind.factory.BreadFactory;
 4import com.abstractFactoryPattern.material.factory.MaterialFactory;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 新加坡奶油口味麪包
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:50
11 **/
12public class SingaporeCreamBread extends BreadFactory {
13    MaterialFactory materialFactory;
14
15    public SingaporeCreamBread(MaterialFactory materialFactory){
16        this.materialFactory=materialFactory;
17        name="新加坡奶油口味";
18        type="4";
19        toSelectAddress();
20    }
21
22    @Override
23    protected void toSelectAddress() {
24        address = materialFactory.selectAddress();
25    }
26    //可以重寫父類方法,進行特殊處理
27}

麪包商店抽象類

 1package com.abstractFactoryPattern.breadStore.factory;
 2
 3import com.abstractFactoryPattern.kind.factory.BreadFactory;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 麪包商店抽象類
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:51
10 **/
11public abstract class BreadStoreFactory {
12
13    public BreadFactory orderBread(String type) {
14
15        BreadFactory bread = createBread(type);
16        //做業務判斷,如果材料耗盡,去拿材料
17        if(1==1){
18            System.out.println("材料耗盡");
19            System.out.println(bread.address.name+"_拿到材料");
20        }
21
22        return   bread.stir()
23                .rubbingRound()
24                .machining()
25                .bake();
26
27    }
28
29    public abstract BreadFactory createBread(String type);
30}

中國店鋪子類,將材料原材料工程,傳遞給BreadFactory的子類對象,再到構造方法

 1package com.abstractFactoryPattern.breadStore.factoryImpl;
 2
 3import com.abstractFactoryPattern.breadStore.factory.BreadStoreFactory;
 4import com.abstractFactoryPattern.kind.factory.BreadFactory;
 5import com.abstractFactoryPattern.kind.factoryImpl.ChinaAppleBread;
 6import com.abstractFactoryPattern.kind.factoryImpl.ChinaCreamBread;
 7import com.abstractFactoryPattern.material.factoryImpl.ChineseMaterialFactory;
 8import com.abstractFactoryPattern.material.factory.MaterialFactory;
 9
10/**
11 * @program: designPattern
12 * @description: 中國店鋪子類
13 * @author: Mr.Yang
14 * @create: 2018-11-18 19:55
15 **/
16public class ChinaStore extends BreadStoreFactory {
17    @Override
18    public BreadFactory createBread(String type) {
19        BreadFactory breadFactory=null;
20        MaterialFactory chineseMaterialFactory = new ChineseMaterialFactory();
21        if("cream".equalsIgnoreCase(type)){
22            System.out.println("創建中國奶油口味麪包");
23            breadFactory=new ChinaCreamBread(chineseMaterialFactory);
24        }else if("apple".equalsIgnoreCase(type)){
25            System.out.println("創建中國蘋果口味麪包");
26            breadFactory=new ChinaAppleBread(chineseMaterialFactory);
27        }else{
28            System.out.println("無法確認的麪包類型");
29            return null;
30        }
31        return breadFactory;
32    }
33}

新加坡店鋪子類,將材料原材料工程,傳遞給BreadFactory的子類對象,再到構造方法

 1package com.abstractFactoryPattern.breadStore.factoryImpl;
 2
 3import com.abstractFactoryPattern.breadStore.factory.BreadStoreFactory;
 4import com.abstractFactoryPattern.kind.factory.BreadFactory;
 5import com.abstractFactoryPattern.kind.factoryImpl.SingaporeAppleBread;
 6import com.abstractFactoryPattern.kind.factoryImpl.SingaporeCreamBread;
 7import com.abstractFactoryPattern.material.factory.MaterialFactory;
 8import com.abstractFactoryPattern.material.factoryImpl.SingaporeMaterialFactory;
 9
10/**
11 * @program: designPattern
12 * @description: 新加坡店鋪子類
13 * @author: Mr.Yang
14 * @create: 2018-11-18 19:56
15 **/
16public class SingaporeStore extends BreadStoreFactory {
17    @Override
18    public BreadFactory createBread(String type) {
19        BreadFactory breadFactory=null;
20        MaterialFactory singaporeMaterialFactory = new SingaporeMaterialFactory();
21        if("cream".equalsIgnoreCase(type)){
22            System.out.println("創建新加坡奶油口味麪包");
23            breadFactory=new SingaporeCreamBread(singaporeMaterialFactory);
24        }else if("apple".equalsIgnoreCase(type)){
25            System.out.println("創建新加坡蘋果口味麪包");
26            breadFactory=new SingaporeAppleBread(singaporeMaterialFactory);
27        }else{
28            System.out.println("無法確認的麪包類型");
29            return null;
30        }
31        return breadFactory;
32    }
33}

泰國店鋪子類,將材料原材料工程,傳遞給BreadFactory的子類對象,再到構造方法

 1package com.abstractFactoryPattern.breadStore.factoryImpl;
 2
 3import com.abstractFactoryPattern.breadStore.factory.BreadStoreFactory;
 4import com.abstractFactoryPattern.kind.factory.BreadFactory;
 5import com.abstractFactoryPattern.kind.factoryImpl.ThailandAppleBread;
 6import com.abstractFactoryPattern.material.factory.MaterialFactory;
 7import com.abstractFactoryPattern.material.factoryImpl.ThailandMaterialFactory;
 8
 9/**
10 * @program: designPattern
11 * @description: 泰國店鋪子類
12 * @author: Mr.Yang
13 * @create: 2018-11-18 19:56
14 **/
15public class ThailandStore extends BreadStoreFactory {
16    @Override
17    public BreadFactory createBread(String type) {
18        BreadFactory breadFactory=null;
19        MaterialFactory thailandMaterialFactory = new ThailandMaterialFactory();
20        if("cream".equalsIgnoreCase(type)){
21            System.out.println("創建泰國奶油口味麪包");
22            breadFactory=new ThailandAppleBread(thailandMaterialFactory);
23        }else if("apple".equalsIgnoreCase(type)){
24            System.out.println("創建泰國蘋果口味麪包");
25            breadFactory=new ThailandAppleBread(thailandMaterialFactory);
26        }else{
27            System.out.println("無法確認的麪包類型");
28            return null;
29        }
30        return breadFactory;
31    }
32}

測試

 1package com.abstractFactoryPattern.patternTest;
 2
 3import com.abstractFactoryPattern.breadStore.factory.BreadStoreFactory;
 4import com.abstractFactoryPattern.breadStore.factoryImpl.ChinaStore;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 測試類
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 20:13
11 **/
12public class Test {
13    public static void main(String[] args) {
14        System.out.println("中國顧客買蘋果味道麪包");
15        BreadStoreFactory chinaBreadStoreFactory = new ChinaStore();
16        chinaBreadStoreFactory.orderBread("apple");
17    }
18}

測試結果

1中國顧客買蘋果味道麪包
2創建中國蘋果口味麪包
3材料耗盡
4中國材料源_拿到材料
5攪拌
6搓圓
7加工
8烘烤

阿三:這裏我使用了抽象工廠模式,提供一個接口,用於創建相關或依賴對象的家族,而不需要明確指定具體的類。他允許了調用方,創建一個相關的產品,但是不需要知道具體的產品是什麼。從具體的產品中解耦,這個是材料源與商店,地址的關係圖

 

項目組長阿飛:是的,抽象工廠經常以工廠方法的方式實現,抽象工廠的任務是定義一個負責創建一組產品的接口(材料提供點),接口內的每個方法都負責創建一個具體的產品(比如創建地址)。然後利用實現抽象工廠的子類來提供這些具體的做法

 

 

JAVA知識分享總結

長按二維碼關注!

 

Gatiln

加我好友!

 

知識分享羣

長按二維碼進羣!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章