前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >抽象工厂模式

抽象工厂模式

作者头像
杨小杰
发布2019-07-04 16:22:09
4170
发布2019-07-04 16:22:09
举报

老板:阿飞,上次面包店老板找我聊了一下,他们是大规模的从各大小原料商铺进的原料,出现了好多偷工减料的情况,现在他们做大了,想自己开几个原料提供点,如果中国的顾客去买,发现原料用尽,就要去找中国原料提供点,拿原料,这个功能看看好不好实现,如果好实现,你就开始做吧!

项目组长阿飞:这个可以实现,我去操作吧

项目组长阿飞:小三,来需求了…………,听懂了吗?你应该知道怎么拓展代码。

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

三天过后。。

阿三:飞哥,设计好了,你看下。

这个是一个地址描述类,主要是表明是哪个地区的,有什么不同,这个是可以拓展的

代码语言:javascript
复制
 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做了一个拓展,可以重写父类方法或者赋值属性,将特殊业务拿到子类去处理,做了个小拓展。

代码语言:javascript
复制
 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}

新加坡地址类,也是一样的。

代码语言:javascript
复制
 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}

泰国的亦是如此

代码语言:javascript
复制
 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}

这是一个材料工程的一个接口类,各大地方具体材料必须实现这个接口类

代码语言:javascript
复制
 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}

中国的原料工程,实现了材料工程的接口类,返回了一个中国的地址类

代码语言:javascript
复制
 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}

新加坡的原料工程,实现了材料工程的接口类,返回了一个新加坡的地址类

代码语言:javascript
复制
 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}

泰国的原料工程,实现了材料工程的接口类,返回了一个泰国的地址类

代码语言:javascript
复制
 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}

面包店的抽象类,进行了微改动,接受了地址类,增加了,去选择地址这个抽象方法,也就意味着,所有实现这个面包工程的将要去实现这个方法

代码语言:javascript
复制
 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}

中国苹果口味的面包,实现抽象方法,重新给父类的几个属性赋值

代码语言:javascript
复制
 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}

中国奶油口味的面包,实现抽象方法,重新给父类的几个属性赋值

代码语言:javascript
复制
 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}

新加坡苹果口味的面包,实现抽象方法,重新给父类的几个属性赋值

代码语言:javascript
复制
 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}

新加坡奶油口味的面包,实现抽象方法,重新给父类的几个属性赋值

代码语言:javascript
复制
 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}

面包商店抽象类

代码语言:javascript
复制
 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的子类对象,再到构造方法

代码语言:javascript
复制
 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的子类对象,再到构造方法

代码语言:javascript
复制
 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的子类对象,再到构造方法

代码语言:javascript
复制
 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}

测试

代码语言:javascript
复制
 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}

测试结果

代码语言:javascript
复制
1中国顾客买苹果味道面包
2创建中国苹果口味面包
3材料耗尽
4中国材料源_拿到材料
5搅拌
6搓圆
7加工
8烘烤

阿三:这里我使用了抽象工厂模式,提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。他允许了调用方,创建一个相关的产品,但是不需要知道具体的产品是什么。从具体的产品中解耦,这个是材料源与商店,地址的关系图

项目组长阿飞:是的,抽象工厂经常以工厂方法的方式实现,抽象工厂的任务是定义一个负责创建一组产品的接口(材料提供点),接口内的每个方法都负责创建一个具体的产品(比如创建地址)。然后利用实现抽象工厂的子类来提供这些具体的做法

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA知识总结与分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档