Java设计模式-创建者模式-工厂模式

工厂模式

  • 工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

工厂模式

要求:由一个特定的工厂提供所需的对象,由工厂来完成对象的创建
工厂模式一般分为三种:简单工厂模式工厂方法模式抽象工厂模式
其中简单工厂模式不属于23种设计模式

简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)

简单工厂模式

简单工厂模式就是 定义了一个创建对象的类,让这个类来封装实例化对象的行为
特点:只有一个工厂,根据入参,通过硬编码的方式创建所需对象。不方便扩展,不建议用
假设:我要开一个小店,卖牛肉包子,猪肉包子
分析上述需求,我们用简单工厂模式实现,如下:

/**
 * 抽象包子类
 **/
public interface Bun {
    void pack();//打包
}

/*************************************************************************/

public class BeefBun implements Bun {
    public BeefBun() {
        System.out.println("包牛肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
public class PorkBun implements Bun {
    public PorkBun() {
        System.out.println("包猪肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
/**
 * 简单包子工厂
 **/
public class BunFactory {

    public Bun createBun(String type){
        Bun bun = null;
        switch (type){
            case "beef":
                bun = new BeefBun();
                break;
            case "pork":
                bun = new PorkBun();
                break;
            default:
                throw new RuntimeException("我不会做");
        }
        return bun;
    }
}

上述代码通过包子工厂 BunFactory,根据入参选择生产不同种类的包子,实现了工厂模式,隐藏了生产细节
测试代码如下:

public class MyStore01 {
    /**
     * 简单工厂模式
     * 只有一个工厂
     */
    BunFactory factory = new BunFactory();


    public Bun order(String type){
        Bun bun = factory.createBun(type);
        //打包...等操作
        bun.pack();
        return bun;
    }
}


/*************************************************************************/
@Test
public void client01(){
    MyStore01 myStore = new MyStore01();
    Bun beef = myStore.order("beef");
    Bun pork = myStore.order("pork");
}
输出:
包牛肉包
包猪肉包

上述代码完成了简单工厂模式的使用,可以隐藏实例的创建,通过工厂对实例进行创建。
但是设想一下,如果需要扩展功能怎么办
假设,我的小店 又要做 香菇菜包,那么势必要修改 BunFactory的代码,很明显,这违反了开闭原则。
那么接下来我们看下 工厂方法模式

工厂方法模式

定义多个工厂,每个工厂生产一种产品
特点:有多个工厂,工厂抽象化,一个具体工厂只生产一个具体产品,容易类爆炸
还是针对上面的需求,开一个小店,卖牛肉,猪肉包子
使用工厂方法模式,实现如下:

/**
 * 抽象包子类
 **/
public interface Bun {
    void pack();//打包
}

/*************************************************************************/

public class BeefBun implements Bun {
    public BeefBun() {
        System.out.println("包牛肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
public class PorkBun implements Bun {
    public PorkBun() {
        System.out.println("包猪肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
/**
* 抽象包子工厂
*/
public interface BunFactory {
    Bun createBun();
}

/*************************************************************************/
/**
* 牛肉包子工厂
*/
public class BeefBunFactory implements BunFactory{
    @Override
    public Bun createBun() {
        return new BeefBun();
    }
}

/*************************************************************************/
/**
* 猪肉包子工厂
*/
public class PorkBunFactory implements BunFactory {
    @Override
    public Bun createBun() {
        return new PorkBun();
    }
}

测试代码:

public class MyStore02 {
    /**
     * 工厂方法模式
     * 有多个工厂,一个工厂只产一种产品
     * @param type
     * @return
     */
    BunFactory factory;

    public void setFactory(BunFactory factory) {
        this.factory = factory;
    }

    public Bun order(){
        Bun bun = factory.createBun();
        //打包...等操作
        bun.pack();
        return bun;
    }
}

@Test
public void client02(){
    MyStore02 myStore = new MyStore02();
    myStore.setFactory(new BeefBunFactory());
    myStore.order();
    myStore.setFactory(new PorkBunFactory());
    myStore.order();
}

输出:
包牛肉包
包猪肉包

上述代码完成了 和简单工厂模式相同的功能,
但是使用工厂方法模式,可以不修改原有代码,通过增加工厂类的方式来扩充功能。

例如:我想增加青菜包的业务,只需要实现一个青菜包类 和 青菜包工厂即可

但是,我们再想一下,新增一个功能要加两个类,如果后面业务越来越广泛,类是不是越来越多,是不是 容易类爆炸。
再思考一下,一个工厂只生产一种产品是不是太浪费了。难道又要回到简单工厂模式了?

当然不是,我们可以折中一下,对工厂类进行更深层的抽象。对产品进行划分,让一个工厂可以生产多种产品,这些产品都是同一组的,相关联的。

下面看下抽象工厂模式

抽象工厂模式

提供一个生产一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

抽象工厂模式比工厂方法模式的抽象程度更高。在工厂方法模式中每一个具体工厂只需要生产一种具体产品,但是在抽象工厂模式中一个具体工厂可以生产一组相关的具体产品,这样一组产品被称为产品族。产品族中的每一个产品都分属于某一个产品继承等级结构。

特点:多个工厂,工厂进行更高层次的抽象,每个工厂生产一个产品族(生产一组相关的具体产品

先引入两个概念:产品族,产品等级结构

  • 产品族:一组相关的具体产品(如海尔旗下的众多产品)。
  • 产品等级结构:每一个产品族都分属于某一个产品继承等级结构(如空调下的多种品牌)。

在前面的工厂方法模式中,考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机。工厂方法模式只考虑生产同等级(同种类被称为同等级)的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调。而抽象工厂模式就考虑了多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,如图所示的是海尔工厂和 TCL 工厂所生产的电视机与空调对应的关系图。
在这里插入图片描述
还是针对我的包子店的需求,我扩充了牛奶的需求。
使用抽象工厂模式开发如下:


/**
 * 抽象包子类
 **/
public interface Bun {
    void pack();//打包
}

/*************************************************************************/

public class BeefBun implements Bun {
    public BeefBun() {
        System.out.println("包牛肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
public class PorkBun implements Bun {
    public PorkBun() {
        System.out.println("包猪肉包");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
/**
*抽象牛奶类
*/
public interface Milk {
    void pack();//打包
}

/*************************************************************************/
public class PureMilk implements Milk{
    public PureMilk() {
        System.out.println("做一杯纯牛奶");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
public class BreakfastMilk implements Milk{
    public BreakfastMilk() {
        System.out.println("做一杯早餐奶");
    }

    @Override
    public void pack() {
    }
}

/*************************************************************************/
/**
*抽象工厂类
*/
public interface Factory {
    Bun createBun();
    Milk createMilk();
}

/*************************************************************************/
/**
*具体工厂类1号,生产牛肉包和纯牛奶
*/
public class PureBeefFactory implements Factory{
    @Override
    public Bun createBun() {
        return new BeefBun();
    }

    @Override
    public Milk createMilk() {
        return new PureMilk();
    }
}

/*************************************************************************/
/**
*具体工厂类2号,生产猪肉包和早餐奶
*/
public class BreakfastPorkFactory implements Factory{
    @Override
    public Bun createBun() {
        return new PorkBun();
    }

    @Override
    public Milk createMilk() {
        return new BreakfastMilk();
    }
}

上述代码中,纯牛奶和牛肉包被看作一个产品族
纯牛奶和早餐奶被看成一个产品等级结构
测试代码:

public class MyStore03 {
    /**
     * 抽象工厂模式
     * 有多个工厂,一个工厂生产一个产品族
     * @param type
     * @return
     */
    Factory factory;

    public void setFactory(Factory factory) {
        this.factory = factory;
    }

    public Bun orderBun(){
        Bun bun = factory.createBun();
        //打包...等操作
        bun.pack();
        return bun;
    }

    public Milk orderMilk(){
        Milk milk = factory.createMilk();
        milk.pack();
        return milk;
    }
}


/*************************************************************************/
/**
 * 抽象工厂模式
 */
@Test
public void client03(){
    MyStore03 myStore = new MyStore03();
    myStore.setFactory(new PureBeefFactory());
    myStore.orderBun();
    myStore.orderMilk();
}
输出:
包牛肉包
做一杯纯牛奶

上述抽象工厂实现了一个工厂创建多个产品的功能,与简单工厂类似,自然有简单工厂类似的缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/128138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SSL证书优惠购买,HTTPS证书双11价格

SSL证书优惠购买哪里有?如何申请HTTPS证书?就看沃通2023“双十一限时特惠”活动,精选HTTPS证书、国密HTTPS证书年度优惠好价,单域名SSL证书、通配符SSL证书任您选择!沃通优惠价格、服务优势,访问沃通CA官网…

为什么说软文推广中了解用户是关键?

数字化时代下软文成为众多企业推广品牌的方式之一,所谓软文,就是指以向用户提供信息,并将产品隐含在信息中的柔性手段。 想要使软文效果明显,就必须深入了解用户,把握其需求、兴趣和行为特点,这也是今天媒…

白嫖阿里云服务器,速看!数量不多

白嫖阿里云服务器攻略来了,在阿里云免费试用中心可以申请免费服务器,但是阿里云百科不建议选择免费的,只有3个月使用时长,选择99元服务器不是更香,2核2G配置3M固定带宽,一年99元,重点是新老用户…

react 修改less文件后保存,内存溢出,项目崩溃问题解决

一、完整报错 一个很老的react项目,因为没有package-lock.json版本锁,导致拉下来的时候,安装的依赖版本冲突,好不容易启动起来,修改less文件后只要一保存,项目就会崩溃,需要重启,报…

如何优雅的开发?试试这个低代码项目

一、前言 众所周知,开发一个大型的企业级系统,公司往往需要大量的人力做支持后盾,如需要需求分析师、数据库管理员、前台美工、后台程序员、测试人员等。 在快速发展中的企业里,尤其是中小企业,都是一个萝卜多个坑&…

说说React的事件机制?

一、是什么 React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等 在React中这套事件机制被称之为合成事件 合成事件(SyntheticEvent) 合成事件是 React模拟原生 DOM事件所有能力的一个事件…

怎么写日语开发信?写外贸日语开发信技巧?

如何写好日语开发信?日语开发信格式是怎么样的? 无论您是初学者还是有经验的营销专家,都需要掌握一些关键技巧,以确保您的邮件在日本市场取得成功。蜂邮将向您介绍怎样写一封令人印象深刻的日语开发信,以吸引潜在客户…

埃隆·马斯克旗下xAI推出PromptIDE工具,加速提示工程和可解释性研究

🦉 AI新闻 🚀 埃隆马斯克旗下xAI推出PromptIDE工具,加速提示工程和可解释性研究 摘要:埃隆马斯克旗下人工智能初创公司xAI推出了PromptIDE工具,该工具是一个用于提示工程和可解释性研究的集成开发环境。通过该工具&a…

2024 年天津专升本招生实施办法(天津专升本文化报名考试时间)

2024 年天津市高职升本科招生实施办法 为做好2024年天津市高职升本科招生工作,天津市招生委员会高等学校招生办公室(以下简称“市高招办”)依据教育部、天津市有关规定,制定本实施办法。 一、招生章程 1.招生学校要制…

C语言求解:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位(约瑟夫问题)

完整代码&#xff1a; /* 有n个人围成一圈&#xff0c;顺序排号。从第一个人开始报数&#xff08;从1到3报数&#xff09;&#xff0c;凡报到3的人 退出圈子&#xff0c;问最后留下的是原来第几号的那位*/ #include<stdio.h>//约瑟夫问题 //递推关系f(n)(f(n-1)2)\mod n…

Python---upper()--转大写///与lower() --转小写

upper()&#xff1a;把字符串全部转换为 大写形式 lower()&#xff1a;把字符串全部转换为 小写形式 upper 英 /ˈʌpə(r)/ adj. 上面的&#xff0c;上层的&#xff0c;较高的&#xff1b;顶部的&#xff0c;上部的&#xff1b;&#xff08;在机构、体系等中&#xff…

单链表(增删改查)【超详细】

目录 单链表 1.单链表的存储定义 2.结点的创建 3.链表尾插入结点 4.单链表尾删结点 5.单链表头插入结点 6.单链表头删结点 7.查找元素&#xff0c;返回结点 8.在pos结点前插入一个结点 ​编辑 9.在pos结点后插入一个结点 10.删除结点 11.删除pos后面的结点 12.修改…

科技改变农业:合成数据农业中的应用

介绍 农业在我们的生活中起着至关重要的作用&#xff0c;它为我们提供了生存的食物。如今&#xff0c;它遇到了各种困难&#xff0c;例如气候变化的影响、缺乏工人以及全球流行病造成的中断。这些困难影响了耕作用水和土地的供应&#xff0c;而这些水和土地正变得越来越稀缺。…

小红书广州探店达人对接流程,小红书达人话术有哪些?

很多时候&#xff0c;在刚开始接触这个行业时&#xff0c;许多人不知道如何对接达人&#xff0c;也不知道如何开口才能一下子打蛇打七寸&#xff0c;有事半功倍之效。今天我们为大家带来小红书广州探店达人对接流程&#xff0c;小红书达人话术有哪些&#xff1f; 1. 自我介绍和…

CAN总线记录诊断助手 CAN记录仪

随着CAN总线的应用市场越来越多&#xff0c;不仅局限于汽车行业&#xff0c;工程车、特种车、消防、医疗等多行业都是以CAN总线通讯为主。总线的调试诊断也成为技术日常工作&#xff0c;有个好的工具能有效帮助发现问题、解决问题。 来可电子的CANLog-VCI是一款即插即用的CAN数…

智汇云舟入选IDC《中国智慧园区解决方案2023年厂商评估》报告

近日&#xff0c;全球领先的市场研究和咨询公司IDC发布报告《中国智慧园区解决方案2023年厂商评估》。报告内&#xff0c;IDC对中国市场具有代表性、且符合评估入围门槛要求的智慧园区解决方案厂商进行了综合评估。智汇云舟凭借在产品、技术等方面的综合优势&#xff0c;与大华…

智汇云舟荣获2023轨道交通国际创新创业大赛“最具市场前景奖”

11月9日&#xff0c;由北京市科学技术委员会、中关村科技园区管理委员会、北京市经济和信息化局、北京市丰台区人民政府、中关村发展集团股份有限公司主办的2023中关村轨道交通国际创新创业大赛总决赛圆满收官。 智汇云舟提报的《视频孪生 改变视界》项目在数百个参赛项目中脱…

IDEA取消git对项目的版本控制

前言 前几天新建项目的时候不小心选了个git仓库&#xff0c;导致这个测试项目一直被git管理着。 解决办法 1 右键项目 选择打开资源目录 2 删除.git文件 把目录下的.git文件删掉 3 删除idea中的git管理 删除完.git文件后&#xff0c;进入idea&#xff0c;右下角会有这样的提…

GoLong的学习之路(二十三)进阶,语法之并发(go最重要的特点)(锁,sync包,原子操作)

这章是我并发系列中最后的一章。这章主要讲的是锁。但是也会讲上一章channl遗留下的一些没有讲到的内容。select关键字的用法&#xff0c;以及错误的一些channl用法。废话不多说。。。 文章目录 select多路复用通道错误示例并发安全和锁问题描述互斥锁读写互斥锁 syncsync.Wait…

Device Partner 平台合作伙伴认证和数据安全保护

Device Partner 平台是面向 AIoT 产业链伙伴的一站式服务平台&#xff0c;伙伴可以通过平台获取最新的产品、服务与解决方案&#xff0c;实现智能硬件产品的开发、认证、量产和推广等全生命周期的管理&#xff0c;加入 HarmonyOS Connect 生态&#xff0c;共同提升消费者的智慧…