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

工厂模式

作者头像
杨小杰
发布2019-07-04 16:31:32
2620
发布2019-07-04 16:31:32
举报

老板:阿飞啊,我们公司最近接了个项目,你看着设计一下,我给你说下需求。 项目组长阿飞:好啊,什么需求? 老板:我们找了一个合作的商铺,他们要设计一套面包销售系统。主要功能,根据用户选择的面包种类来下订单,面包目前有奶油口味面包和苹果口味面包,所有面包的制作流程都是---搅拌,搓圆,加工,烘烤。 项目组长阿飞:好的,我去想想怎么设计。 项目组长阿飞:小三啊,我给你个任务,…………,听懂了吗? 阿三:听懂了,飞哥。 项目组长阿飞:嗯嗯,好的,这个任务就交给你了,我要去处理点事情,我相信你。 阿三:。。。 三天过后。 阿三:飞哥,设计好了,你看下。

 1package com.factoryPattern.breadKind.factory;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 面包口味的抽象类
 6 * @author: Mr.Yang
 7 * @create: 2018-11-18 19:24
 8 **/
 9public abstract class BreadFactory {
10    protected String name;
11    protected String type;
12
13    public BreadFactory stir(){
14        System.out.println("搅拌");
15        return this;
16    }
17
18    public BreadFactory rubbingRound(){
19        System.out.println("搓圆");
20        return this;
21    }
22
23    public BreadFactory machining(){
24        System.out.println("加工");
25        return this;
26    }
27    public BreadFactory bake(){
28        System.out.println("烘烤");
29        return this;
30    }
31
32    public String getName() {
33        return name;
34    }
35
36    public BreadFactory setName(String name) {
37        this.name = name;
38        return this;
39    }
40
41    public String getType() {
42        return type;
43    }
44
45    public BreadFactory setType(String type) {
46        this.type = type;
47        return this;
48    }
49}

现在已有的两种口味继承这个抽象类--奶油面包

 1package com.factoryPattern.breadKind;
 2
 3import com.factoryPattern.breadKind.factory.BreadFactory;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 奶油味面包
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:24
10 **/
11public class CreamBread extends BreadFactory {
12    public CreamBread(){
13        name="奶油味";
14        type="2";
15    }
16    //可以重写父类方法,进行特殊处理
17}

苹果味面包

 1package com.factoryPattern.breadKind;
 2
 3import com.factoryPattern.breadKind.factory.BreadFactory;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 苹果味面包
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:25
10 **/
11public class AppleBread extends BreadFactory {
12    public AppleBread(){
13        name="苹果味";
14        type="1";
15    }
16    //可以重写父类方法,进行特殊处理
17}

然后是销售系统

 1package com.factoryPattern.breadKind.breadOrder;
 2
 3import com.factoryPattern.breadKind.AppleBread;
 4import com.factoryPattern.breadKind.CreamBread;
 5import com.factoryPattern.breadKind.factory.BreadFactory;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 面包订单销售类
10 * @author: Mr.Yang
11 * @create: 2018-11-18 19:26
12 **/
13public class BreadOrder {
14
15
16    BreadFactory orderBread(String type){
17        BreadFactory breadFactory;
18        if("cream".equalsIgnoreCase(type)){
19            System.out.println("创建奶油口味面包");
20            breadFactory=new CreamBread();
21        }else if("apple".equalsIgnoreCase(type)){
22            System.out.println("创建苹果口味面包");
23            breadFactory=new AppleBread();
24        }else{
25            System.out.println("无法确认的面包类型");
26            return null;
27        }
28
29        return breadFactory.stir()
30                .rubbingRound()
31                .machining()
32                .bake();
33    }
34}

项目组长阿飞:三啊,不错,学会使用抽象了,但是如果我还要增加好几种面包类型呢?阿尔法面包销售不好,不想做这个了呢?之前给你说过设计模式的原则之一,对拓展开放,对修改关闭。如果有改动,可能会一直在这个代码的基础上累加做修改的。最好把创建对象的代码与销售的代码分隔开。 阿三:好的,我再修改修改(真的是,搞这么麻烦干嘛!) 又三天过后。 阿三:飞哥,修改好了,你看下。

新增了一个工程类

 1package com.factoryPattern.breadCreate;
 2
 3import com.factoryPattern.breadKind.AppleBread;
 4import com.factoryPattern.breadKind.CreamBread;
 5import com.factoryPattern.breadKind.factory.BreadFactory;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 面包创建工程
10 * @author: Mr.Yang
11 * @create: 2018-11-18 19:37
12 **/
13public class BreadCreateFactory {
14    public BreadFactory createBread(String type){
15        BreadFactory breadFactory=null;
16        if("cream".equalsIgnoreCase(type)){
17            System.out.println("创建奶油口味面包");
18            breadFactory=new CreamBread();
19        }else if("apple".equalsIgnoreCase(type)){
20            System.out.println("创建苹果口味面包");
21            breadFactory=new AppleBread();
22        }else{
23            System.out.println("无法确认的面包类型");
24            return null;
25        }
26        return breadFactory;
27    }
28}

修改了销售类

 1package com.factoryPattern.breadKind.breadOrder;
 2
 3import com.factoryPattern.breadCreate.BreadCreateFactory;
 4import com.factoryPattern.breadKind.factory.BreadFactory;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 面包订单销售类
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:26
11 **/
12public class BreadOrder {
13    BreadCreateFactory breadCreateFactory;
14
15    public BreadOrder(BreadCreateFactory breadCreateFactory) {
16        this.breadCreateFactory = breadCreateFactory;
17    }
18
19    BreadFactory orderBread(String type) {
20        return breadCreateFactory.createBread(type)
21                .stir()
22                .rubbingRound()
23                .machining()
24                .bake();
25    }
26}

项目组长阿飞:不错,这是一个简单工厂,但是你要记住,这并不是一个设计模式,而是一个编程习惯,一个不错的编程习惯,简单工厂把全部的事情,在一个地方处理完了,工厂方法是创建一个框架,让子类决定如何实现。还有领导说需求变了,这个面包店开了分店,一个在泰国,一个在新加坡,你看着再修改下吧,你可以考虑加入工厂方法。 阿三:好的(我服了,真的是****) 又三天过后。 阿三:飞哥,修改好了,这是完整代码,你看下。 先是一个面包商店抽象类

 1package com.factoryPattern.breadStore;
 2
 3import com.factoryPattern.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        return createBread(type)
15                .stir()
16                .rubbingRound()
17                .machining()
18                .bake();
19    }
20
21    abstract BreadFactory createBread(String type);
22}

创建一个中国店铺子类实现商店抽象类

 1package com.factoryPattern.breadStore;
 2
 3import com.factoryPattern.factory.BreadFactory;
 4import com.factoryPattern.kind.ChinaAppleBread;
 5import com.factoryPattern.kind.ChinaCreamBread;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 中国店铺子类
10 * @author: Mr.Yang
11 * @create: 2018-11-18 19:55
12 **/
13public class ChinaStore extends BreadStoreFactory{
14    @Override
15    BreadFactory createBread(String type) {
16        BreadFactory breadFactory=null;
17        if("cream".equalsIgnoreCase(type)){
18            System.out.println("创建中国奶油口味面包");
19            breadFactory=new ChinaCreamBread();
20        }else if("apple".equalsIgnoreCase(type)){
21            System.out.println("创建中国苹果口味面包");
22            breadFactory=new ChinaAppleBread();
23        }else{
24            System.out.println("无法确认的面包类型");
25            return null;
26        }
27        return breadFactory;
28    }
29}

创建一个新加坡店铺子类

 1package com.factoryPattern.breadStore;
 2
 3import com.factoryPattern.factory.BreadFactory;
 4import com.factoryPattern.kind.SingaporeAppleBread;
 5import com.factoryPattern.kind.SingaporeCreamBread;
 6
 7/**
 8 * @program: designPattern
 9 * @description: 新加坡店铺子类
10 * @author: Mr.Yang
11 * @create: 2018-11-18 19:56
12 **/
13public class SingaporeStore extends BreadStoreFactory {
14    @Override
15    BreadFactory createBread(String type) {
16        BreadFactory breadFactory=null;
17        if("cream".equalsIgnoreCase(type)){
18            System.out.println("创建新加坡奶油口味面包");
19            breadFactory=new SingaporeCreamBread();
20        }else if("apple".equalsIgnoreCase(type)){
21            System.out.println("创建新加坡苹果口味面包");
22            breadFactory=new SingaporeAppleBread();
23        }else{
24            System.out.println("无法确认的面包类型");
25            return null;
26        }
27        return breadFactory;
28    }
29}

创建一个泰国店铺子类

 1package com.factoryPattern.breadStore;
 2
 3import com.factoryPattern.factory.BreadFactory;
 4import com.factoryPattern.kind.ThailandAppleBread;
 5
 6/**
 7 * @program: designPattern
 8 * @description: 泰国店铺子类
 9 * @author: Mr.Yang
10 * @create: 2018-11-18 19:56
11 **/
12public class ThailandStore extends BreadStoreFactory {
13    @Override
14    BreadFactory createBread(String type) {
15        BreadFactory breadFactory=null;
16        if("cream".equalsIgnoreCase(type)){
17            System.out.println("创建泰国奶油口味面包");
18            breadFactory=new ThailandAppleBread();
19        }else if("apple".equalsIgnoreCase(type)){
20            System.out.println("创建泰国苹果口味面包");
21            breadFactory=new ThailandAppleBread();
22        }else{
23            System.out.println("无法确认的面包类型");
24            return null;
25        }
26        return breadFactory;
27    }
28}

面包口味的抽象类

 1package com.factoryPattern.factory;
 2
 3/**
 4 * @program: designPattern
 5 * @description: 面包口味的抽象类
 6 * @author: Mr.Yang
 7 * @create: 2018-11-18 19:24
 8 **/
 9public abstract class BreadFactory {
10    protected String name;
11    protected String type;
12
13    public BreadFactory stir(){
14        System.out.println("搅拌");
15        return this;
16    }
17
18    public BreadFactory rubbingRound(){
19        System.out.println("搓圆");
20        return this;
21    }
22
23    public BreadFactory machining(){
24        System.out.println("加工");
25        return this;
26    }
27    public BreadFactory bake(){
28        System.out.println("烘烤");
29        return this;
30    }
31
32    public String getName() {
33        return name;
34    }
35
36    public BreadFactory setName(String name) {
37        this.name = name;
38        return this;
39    }
40
41    public String getType() {
42        return type;
43    }
44
45    public BreadFactory setType(String type) {
46        this.type = type;
47        return this;
48    }
49}

中国苹果口味面包

 1package com.factoryPattern.kind;
 2
 3import com.factoryPattern.factory.BreadFactory;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 中国苹果口味面包
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:48
10 **/
11public class ChinaAppleBread  extends BreadFactory {
12    public ChinaAppleBread(){
13        name="中国苹果口味";
14        type="1";
15    }
16    //可以重写父类方法,进行特殊处理
17}

中国奶油口味面包

 1package com.factoryPattern.kind;
 2
 3import com.factoryPattern.factory.BreadFactory;
 4
 5/**
 6 * @program: designPattern
 7 * @description: 中国奶油口味面包
 8 * @author: Mr.Yang
 9 * @create: 2018-11-18 19:48
10 **/
11public class ChinaCreamBread extends BreadFactory {
12    public ChinaCreamBread(){
13        name="中国奶油口味";
14        type="2";
15    }
16    //可以重写父类方法,进行特殊处理
17}

还有新加坡苹果口味面包,新加坡奶油口味面包,泰国苹果口味面包,泰国奶油口味面包

测试类

 1package com.factoryPattern.patternTest;
 2
 3import com.factoryPattern.breadStore.BreadStoreFactory;
 4import com.factoryPattern.breadStore.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烘烤

项目组长阿飞:看着不错,给我讲解一下吧。 阿三:我所用的是设计模式中的工厂模式,让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。我简单的画了个图

阿三:大致如图,工程模式的定义:定义了一个创建对象的接口,但有子类决定要实例化的类是哪一个。工程方法让类把实例化推迟到子类

项目组长阿飞:很好,看来你已经掌握了工程模式的精髓,工程模式遵循了一个设计原则:“要依赖抽象,不要依赖具体实现。”,它有一个响亮的名字:“依赖倒置原则”。 你看你这两个图。创建者抽象BreadStoreFactory依赖与BreadFactory抽象类,面包的具体实现(chinaAppleBread,chinaCreamBread)依赖与BreadFactory抽象类,想要遵循依赖倒置原则,工程方法并非是唯一的,但是确是最有威力的技巧之一。

阿三:好的(我早就知道了---膨胀的一批)

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

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

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

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

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