晒百科
当前位置: 首页 常识

什么是工厂模式(创建型-工厂模式(Factory Pattern))

2024-07-31 08:15:33 100次浏览   

  我们来学习工厂模式,有的小伙伴可能会说起航篇里的大纲中没有这个模式呀,这是从哪冒出来的。事实确实如此,工厂模式包含了简单工厂模式、工厂方法模式和抽象工厂模式。

  简单工厂模式也没有在大纲中出现,这个是较早出现的工厂模式。

  什么是工厂模式

  大白话来说就是,当我们需要一个对象时,不需要知道具体的创建过程,只需要问工厂要即可。由此可见,工厂的作用就是为我们创建对象。

  举个栗子,比如你要去买书,可能想买《Java编程思想》,也可能是《Effective Java》又或者是《深入理解Java虚拟机》,这种情况下直接去书店就能满足你的需求。这里的书店就充当工厂的作用。

  简单工厂(Simple Factory)

  简单工厂模式也叫静态工厂方法,根据传入的参数不同返回相应的对象。实现该方法所在的类就是简单工厂类。如下图所示:

  这里以支付为例,日常生活中大家在付款时,用的比较多的就是支付宝和微信了。根据这个场景我们来实现简单工厂的代码。

  第一步:创建支付接口

/**
 * 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
 */
public interface IPay {

    /**
     * 定义统一支付方法
     */
    void unifiedorder();
}12345678910复制代码类型:[java]

  第二步:创建具体的业务实现

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class AliPay implements IPay {

    @Override
    public void unifiedorder() {
        System.out.println("调用阿里支付");
    }
}

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class WechatPay implements IPay{

    @Override
    public void unifiedorder() {
        System.out.println("调用微信支付");
    }
}123456789101112131415161718192021复制代码类型:[java]

  第三步:创建简单工厂

/**
 * 第三步:创建简单工厂类,负责创建用户所需的对象
 */
public class SimplePayFactory {

    /**
     * 获取支付对象方法
     * @param beanName
     * @return
     */
    public static IPay getPayInstance(String beanName) {
        if (beanName.equalsIgnoreCase("AliPay")) {
            return new AliPay();
        } else if (beanName.equalsIgnoreCase("WechatPay")) {
            return new WechatPay();
        } else {
            return null;
        }
    }
}1234567891011121314151617181920复制代码类型:[java]

  第四步:测试

public class SimpleFactoryTest {

    public static void main(String[] args) {
        IPay aliPay = SimplePayFactory.getPayInstance("AliPay");
        aliPay.unifiedorder();
        IPay wechatPay = SimplePayFactory.getPayInstance("WechatPay");
        wechatPay.unifiedorder();
    }
}123456789复制代码类型:[java]

  运行结果:

调用阿里支付
调用微信支付12复制代码类型:[java]

  优点:解耦

  缺点:

  违背开闭原则,新增Product类需要修改 getPayInstance 代码

  一定程度上增加了类的数量

  不利于系统的维护和扩展

  工厂方法(Factory Method)

  工厂方法模式又称工厂模式,是简单工厂的一个变种,解决了开闭原则问题。用户只需要知道具体工厂的名称就可以拿到相应的对象。如下图所示:

  还是以支付为例,在工厂方法中,原有内容保持不变,但多了一层获取具体工厂的接口。

  第一步:创建支付接口

**
 * 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
 */
public interface IPay {

    /**
     * 定义统一支付方法
     */
    void unifiedorder();
}12345678910复制代码类型:[java]

  第二步:创建具体的业务实现

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class AliPay implements IPay {

    @Override
    public void unifiedorder() {
        System.out.println("调用阿里支付");
    }
}

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class WechatPay implements IPay{

    @Override
    public void unifiedorder() {
        System.out.println("调用微信支付");
    }
}123456789101112131415161718192021复制代码类型:[java]

  第三步:创建获取支付对象的工厂

/**
 * 第三步:抽象工厂类,用于描述具体工厂的公共接口
 */
public interface IPayFactory {

    /**
     * 具体工厂的抽象方法
     * @return IPay
     */
    IPay getPay();
}1234567891011复制代码类型:[java]

  第四步:创建具体工厂类

/**
 * 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
 */
public class AlipayFactory implements IPayFactory{

    @Override
    public IPay getPay() {
        return new AliPay();
    }
}

/**
 * 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
 */
public class WechatFactory implements IPayFactory{

    @Override
    public IPay getPay() {
        return new WechatPay();
    }
}123456789101112131415161718192021复制代码类型:[java]

  第五步:测试

public class MethodFactoryTest {

    public static void main(String[] args) {
        IPayFactory alipayFactory = new AlipayFactory();
        IPay aliPay = alipayFactory.getPay();
        aliPay.unifiedorder();
        IPayFactory wechatFactory = new WechatFactory();
        IPay wechatPay = wechatFactory.getPay();
        wechatPay.unifiedorder();
    }
}
123456789101112复制代码类型:[java]

  运行结果:

调用阿里支付
调用微信支付12复制代码类型:[java]

  优点:

  解耦

  符合开闭原则

  提高了扩展性和复用性

  缺点:

  类数量过多,工厂越多复杂性越高

  更具抽象性,增加了理解成本

  抽象产品接口只能生产一种产品

  抽象工厂(Abstract Factory)

  通过工厂方法的学习,大家也可以感觉到该模式只考虑同类型的产品,但是生活中同样有很多综合型的工厂,如大学有很多的专业,企业里有很多的岗位等等,这就造就了抽象工厂模式。

  为了更好的理解抽象工厂,我们先来了解下产品的相关概念,如下图所示:

  简单工厂模式不建议在产品种类多的情况下使用

  接下来就以苹果和华为公司生产电脑和手机为例,实现抽象工厂。如下图所示:

  第一步:创建产品工厂

/**
 * 第一步:创建电脑工厂,并定义功能
 */
public interface IComputerFactory {

    /**
     * 开机
     */
    void start();

    /**
     * 关机
     */
    void stop();
}

/**
 * 第一步:创建手机工厂,并定义功能
 */
public interface IPhoneFactory {

    /**
     * 开机
     */
    void start();

    /**
     * 关机
     */
    void stop();
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]

  第二步:创建具体产品

  创建苹果产品: 

/**
 * 第二步:创建具体产品(苹果电脑)
 */
public class Mac implements IComputerFactory{
    @Override
    public void start() {
        System.out.println("苹果电脑开机");
    }

    @Override
    public void stop() {
        System.out.println("苹果电脑关机");
    }
}

/**
 * 第二步:创建具体产品(苹果手机)
 */
public class IPhone implements IPhoneFactory{

    @Override
    public void start() {
        System.out.println("苹果手机开机");
    }

    @Override
    public void stop() {
        System.out.println("苹果手机关机");
    }
}123456789101112131415161718192021222324252627282930复制代码类型:[java]

  创建华为产品:

/**
 * 第二步:创建具体产品(华为电脑)
 */
public class HuaWeiComputer implements IComputerFactory{
    @Override
    public void start() {
        System.out.println("华为电脑开机");
    }

    @Override
    public void stop() {
        System.out.println("华为电脑关机");
    }
}

/**
 * 第二步:创建具体产品(华为手机)
 */
public class HuaWeiPhone implements IPhoneFactory{

    @Override
    public void start() {
        System.out.println("华为手机开机");
    }

    @Override
    public void stop() {
        System.out.println("华为手机关机");
    }
}123456789101112131415161718192021222324252627282930复制代码类型:[java]

  第三步:创建企业工厂

/**
 * 第三步:创建企业工厂(苹果工厂)
 */
public class AppleFactory implements IProductFactory{

    @Override
    public IPhoneFactory phoneProduct() {
        return new IPhone();
    }

    @Override
    public IComputerFactory computerProduct() {
        return new Mac();
    }
}

/**
 * 第三步:创建企业工厂(华为工厂)
 */
public class HuaWeiFactory implements IProductFactory{

    @Override
    public IPhoneFactory phoneProduct() {
        return new HuaWeiPhone();
    }

    @Override
    public IComputerFactory computerProduct() {
        return new HuaWeiComputer();
    }
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]

  第四步:创建最上层抽象工厂

/**
 * 第四步:创建最上层抽象工厂
 */
public interface IProductFactory {

    /**
     * 生产手机
     * @return IPhoneFactory
     */
    IPhoneFactory phoneProduct();

    /**
     * 生产电脑
     * @return IComputerFactory
     */
    IComputerFactory computerProduct();
}1234567891011121314151617复制代码类型:[java]

  第五步:抽象工厂测试

public class AbstractFactoryTest {

    public static void main(String[] args) {
        // 苹果产品系列
        IProductFactory appleFactory = new AppleFactory();
        IComputerFactory appleComputerFactory = appleFactory.computerProduct();
        appleComputerFactory.start();
        appleComputerFactory.stop();
        IPhoneFactory applePhoneFactory = appleFactory.phoneProduct();
        applePhoneFactory.start();
        applePhoneFactory.stop();
        System.out.println("======================");
        // 华为产品系列
        IProductFactory huaWeiFactory = new HuaWeiFactory();
        IComputerFactory huaWeiComputerFactory = huaWeiFactory.computerProduct();
        huaWeiComputerFactory.start();
        huaWeiComputerFactory.stop();
        IPhoneFactory huaWeiPhoneFactory = huaWeiFactory.phoneProduct();
        huaWeiPhoneFactory.start();
        huaWeiPhoneFactory.stop();
    }
}12345678910111213141516171819202122复制代码类型:[java]

  运行结果:

苹果电脑开机
苹果电脑关机
苹果手机开机
苹果手机关机
====分割线====
华为电脑开机
华为电脑关机
华为手机开机
华为手机关机123456789复制代码类型:[java]

  优点:工厂方法的扩展,实现了产品族生产。

  缺点:

  不是很符合开闭原则

  产品族扩展困难

  比工厂方法更抽象,理解更困难

  总结

  通过本篇文章的学习,总结以下几点:

  简单工厂模式不建议在产品种类多的情况下使用

  工厂方法模式适用于多种厂家生产类似产品,项目中使用频率较低

  抽象工厂是工厂方法的扩展,实现了产品族生产

  抽象工厂在实际开发中的出现的频率更低

  抽象工厂中每个工厂只生产一个产品时建议使用工厂方法




是工厂方法的扩展,实现了产品族生产

  抽象工厂在实际开发中的出现的频率更低

  抽象工厂中每个工厂只生产一个产品时建议使用工厂方法



相关推荐
家居电动窗帘出现故障怎么处理?
家居电动窗帘出现故障怎么处理?

随着科学技术的发展,人们对生活质量的追求不断提高,无线智能家居越来越容易被人们接受和应用,越来越多的电动窗帘产品进入人们的生活。 随之,也产生了如果电动窗帘维护不当,容易引起电动窗帘故障的问题。 现在,让我们来看看无线智能家居的自控窗帘应该如何维护。电动窗帘开关不好,或者中途不能靠近。 由于手动或其

屋面漏水的原因有哪些?屋面漏水的解决办法
屋面漏水的原因有哪些?屋面漏水的解决办法

屋面出现漏水的问题,对日常的生活也会带来极大的影响,但屋面却经常会有漏水的问题,屋面漏水的原因有哪些?面对屋面有漏水的问题,及时快速的解决才是关键,如不解决后果也会特别的严重,来看看屋面漏水的解决办法有哪些。一、屋面漏水的原因有哪些?1、现浇板渗漏原因有两点:现浇板内预埋接线盒上浮,使雨水直接从接线

热门文章
1
地铁买票怎么买全程(手把手教你坐地铁!)
地铁买票怎么买全程(手把手教你坐地铁!)

坐地铁对大多数人来说是很简单的事,但还是有很多人第一次进城里,从未坐过地铁。转发给他,手把手坐地铁教程来啦!首先,找到一个地铁站口,随便哪个都行,顺着扶梯下去。下了扶梯,跟着箭头往前走。坐地铁需要买地铁票,有三种乘车方式:1.在自助售票机前进行买票操作:选择乘车路线—选择站台—选择几张票—选择付款方

2
如何开药店 想当药店老板的注意了!开药店需要这些证照!
如何开药店 想当药店老板的注意了!开药店需要这些证照!

如果您想开药店,当老板,那么一定要了解开药店最需要办理哪些基本证照?证照的经营范围有哪些?办理过程中,需要提交哪些材料?以及其他一些细节方面的问题...等等。尤其对于很多不是这个行业的人来说,可能一头雾水,下面北京百草堂药店加盟为大家梳理了个人开药店所需的证照资料,一起来看看吧!证照一:营业执照药店

3
馄饨侯简介(老北京的京味馄饨)
馄饨侯简介(老北京的京味馄饨)

馄饨侯的由来“馄饨侯”其人,姓侯名庭杰。在北京东安门大街16号门前摆摊卖馄饨。当年的东安门、王府井是京城最繁华的商业街区,有人民艺术剧院、东安市场、吉祥戏院等。晚上一散戏,人们都来吃夜宵。当时人们对“馄饨侯”的评价有四:一为皮薄,二为馅细,三为汤鲜,四为人缘好。馄饨的特点是皮薄、馅细、汤好、作料全

4
关于放下执念的禅语语录
关于放下执念的禅语语录

人们总是执着于心中执念,执迷不悟,放下执念,万般自在。分享一些关于放下执念的禅语,愿你早日大彻大悟,活出自我。既是劝别人,也是劝自己。所有的压力都来自于太想要了,调整好心态,慢即是稳,稳即是进解决失望和害怕的方式是停止期待.♡缘分不是求来的是修来的尽力争取就好上天自有安排光是抓不住的雾也会消散 人

5
杨梅水怎么洗才干净(杨梅好吃却不好洗?)
杨梅水怎么洗才干净(杨梅好吃却不好洗?)

在日常生活中,杨梅是许多人都非常喜欢吃的一种水果,但是在买回来之后很多人都会发愁,这种水果怎么洗才能更干净呢?毕竟因为杨梅的构造不同,所以杨梅中不仅仅能够隐藏赃物,而且还有一些眼睛看不到的虫子,甚至还有可能浑身都藏满了农药,不过今天小编就是来跟大家分享几种方法,能够将杨梅清洗的干净又美味。第一种、盐

6
fastboot模式怎么解除(什么是刷机中的FASTBOOT)
fastboot模式怎么解除(什么是刷机中的FASTBOOT)

1. 什么是手机上的FASTBOOT模式?顾名思义,FASTBOOT这个名词可以理解为“快速启动”的中文意思。但在安卓手机中,则代指一种比Recovery更底层的刷机救援模式,亦被称作“引导模式”、“线刷模式”或“Bootloader模式”。与主要采用手机屏幕及实体按键交互的Recovery模式不同

7
玉石的鉴别方法大全(玉石鉴定秘籍:揭开神秘面纱)
玉石的鉴别方法大全(玉石鉴定秘籍:揭开神秘面纱)

《玉石鉴定秘籍:揭开神秘面纱》在珠宝的世界里,玉石犹如一颗璀璨的明珠,散发着独特的魅力。然而,要准确鉴定玉石并非易事,这可是一项需要专业知识和敏锐眼光的技艺。首先,我们来谈谈玉石的质地。优质的玉石质地温润细腻,犹如羊脂一般光滑。据统计,超过 80%的顶级玉石都具备这样的特质。比如说和田玉,其质地紧密

8
正宗的豆角焖面怎么做简单好吃(豆角焖面,简单好做又好吃)
正宗的豆角焖面怎么做简单好吃(豆角焖面,简单好做又好吃)

豆角焖面,是一种传统的特色面食。因为是利用水蒸气将面条、豆角等食材焖熟而成,所以就叫做豆角焖面。天热的时候,吃上一碗豆角焖面,喝上一杯凉白开,那感觉真是太实在了!小时候,在外面玩累了,饿了,回到家里看到妈妈做的一锅豆角焖面,那香气直往人的鼻子里钻, 肚子更是饿得咕咕直叫了!赶紧让妈妈给自己一碗,大口

9
北戴河三天两晚旅游路线攻略 ,必玩景点介绍,注意事项避坑指南。
北戴河三天两晚旅游路线攻略 ,必玩景点介绍,注意事项避坑指南。

暑假带孩子看海玩水,去北戴河绝对是首选,能看到美景,也能看到沙滩,好玩的地方也不少。我整理了一条三天两晚的线路,请大家点赞收藏。游玩线路第1天我坐的是动车到达北戴河动车站,入住的地方是在刘庄夜市附近,打车过去花了30元,用了28分钟,由于刘庄附近堵车所以稍微晚了点到达。千万别选择在秦皇岛站下车,那里

10
男士保养皮肤的方法,没那么复杂!别掉进男士专用陷阱
男士保养皮肤的方法,没那么复杂!别掉进男士专用陷阱

这还真不一定!大部分女生都护肤对吧,而且都很用心的护肤。但如果你仔细观察不难发现,身边很多整天用心护肤的精致女孩可能皮肤反而不如不护肤的男士。所以,准确来说应该是:会护肤的男生比不会护肤的男生会更显年轻!到底什么才是会护肤?怎么样的护肤才是正确护肤呢?这是我们要关注的重点。男性到底该如何高效护肤?从