Java设计模式中工厂模式是啥?静态工厂、简单工厂与抽象工厂,工厂方法模式又是啥,怎么用,

news2025/7/4 18:55:57

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

4.3 工厂模式

4.3.1 背景

  • 若创建对象时直接new对象,则会使对象耦合严重,更换对象则很复杂

4.3.2 简单工厂

4.3.3 特点

  • 不是一种设计模式,是编程习惯

4.3.4 结构

  • 抽象产品:定义产品规范,描述产品主要功能特性
  • 具体产品:实现或继承抽象产品子类
  • 具体工厂:提供创建产品方法,调用通过方法来获取产品

4.3.4 特点

4.3.4.1 优点
  • 将对象创建过程与业务逻辑分来,避免修改客户代码
  • 降低耦合性,易于扩展
4.3.4.2缺点
  • 增加新功能需要修改工厂类代码,违背“开闭原则”

4.3.5 案例(咖啡店点咖啡)

  • 抽象咖啡
public abstract class Coffee {  
    public abstract String getName();  
//    加糖  
    public void addSugar() {  
        System.out.println("加糖");  
    }  
//    加奶  
    public void addMilk() {  
        System.out.println("加奶");  
    }  
}
  • 美式咖啡
public class AmericanCoffee extends Coffee{  
    @Override  
    public String getName() {  
        return "美式咖啡";  
    }  
}
  • 拿铁咖啡
public class LatteCoffee extends Coffee{  
    @Override  
    public String getName() {  
        return "拿铁咖啡";  
    }  
}
  • 咖啡简单工厂
public class CoffeeSimpleFactory {  
    public Coffee createCoffeeFactory(String type)  
    {  
        Coffee coffee;  
        if(type.equals("American"))  
            coffee= new AmericanCoffee();  
        else if(type.equals("Latte"))  
            coffee= new LatteCoffee();  
        else throw new RuntimeException("对不起,您的咖啡本店没有!请重新点");  
        return coffee;  
    }  
}
  • 咖啡店
public class CoffeeStore {  
    public Coffee orderCoffee(String type)  
    {  
        CoffeeSimpleFactory coffeeSimpleFactory = new CoffeeSimpleFactory();  
        Coffee coffee = coffeeSimpleFactory.createCoffeeFactory(type);  
//        加糖  
        coffee.addSugar();  
//        加奶  
        coffee.addMilk();  
        return coffee;  
    }  
}
  • 测试
public static void main(String[] args) {  
    CoffeeStore coffeeStore = new CoffeeStore();  
    Coffee coffee = coffeeStore.orderCoffee("American");  
    System.out.println(coffee.getName());  
}

如图![[Pasted image 20221228222406.png]]

4.3.6 扩展(咖啡店点咖啡)

  • 更改工厂类代码如图![[Pasted image 20221228223356.png]]
  • 更改咖啡店代码如图![[Pasted image 20221228223428.png]]

4.3.3 工厂方法

4.3.3.1 案例

案例与简单工厂一样

4.3.3.2 结构

  • 抽象工厂:提供创建产品接口,调用者通过访问具体工厂来创建产品
  • 具体工厂:实现抽象工厂抽象方法,完成具体产品创建
  • 抽象产品:定义产品规范,描述产品功能和特性
  • 具体产品:实现抽象产品定义接口

4.3.3.3 特点

4.3.3.3.1 优点
  • 用户只需知道具体工厂名称即可得到产品
  • 系统增加新产品只需添加具体产品类和具体工厂类即可,无需修改原工厂
4.3.3.3.2 缺点

每增加新产品就得增加具体产品和对应具体工厂类

4.3.3.4 代码

  • 其它不变
  • 咖啡创建工厂接口
public interface CoffeeFactory {  
    public Coffee createCoffee();  
}
  • 美式咖啡创建工厂
public class AmericanCoffeeFactory implements CoffeeFactory{  
    @Override  
    public Coffee createCoffee() {  
        return new AmericanCoffee();  
    }  
}
  • 拿铁咖啡创建工厂
public class LatteCoffeeFactory implements CoffeeFactory{  
    @Override  
    public Coffee createCoffee() {  
        return new LatteCoffee();  
    }  
}
  • 咖啡店
public class CoffeeStore {  
    private CoffeeFactory coffeeFactory;  
    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {  
        this.coffeeFactory = coffeeFactory;  
    }  
    public Coffee orderCoffee()  
    {  
        Coffee coffee = coffeeFactory.createCoffee();  
//        加糖  
        coffee.addSugar();  
//        加奶  
        coffee.addMilk();  
        return coffee;  
    }  
}
  • 测试,结果正确,美式咖啡
public static void main(String[] args) {  
    CoffeeStore coffeeStore = new CoffeeStore();  
    coffeeStore.setCoffeeFactory(new AmericanCoffeeFactory());  
    Coffee coffee = coffeeStore.orderCoffee();  
            System.out.println(coffee.getName());  
}
  • 关系图![[Pasted image 20221229161057.png]]

4.3.4 抽象工厂

4.3.4.1 概念

  • 工厂方法模式升级版,可生产多个等级产品
  • 一种为访问类提供一个创建一组相关或相互依赖对象接口,且访问类无需指定索要产品具体类即可得到同组不同产品

4.3.4.2 结构

  • 抽象工厂:提供多个创建产品接口,可创建多个不同等级产品
  • 具体工厂:实现抽象工厂多个抽象方法
  • 抽象产品:定义规范,描述功能
  • 具体产品:实现接口,由具体工厂来创建,同具体工厂实多对一关系

4.3.4.3 特点

4.3.4.3.1 优点

当产品族中多个对象被设计一起工作时,能保证客户端始终使用同一个产品族中的对象

4.3.4.3.2 缺点

当产品族中需要增加产品时,所有工厂类均需要修改

4.3.4.4 使用场景

  • 当需要创建对象是一系列相互关联或依赖产品时
  • 系统有多个产品族,但每次只使用其中的某一族产品
  • 系统提供产品类库,且所有产品接口相同,客户端不依赖产品实例创建细节和内部结构

4.3.4.5 案例(咖啡店)

  • 咖啡与甜点抽象类
public abstract class Coffee {  
    public abstract String getName();  
//    加糖  
    public void addSugar() {  
        System.out.println("加糖");  
    }  
//    加奶  
    public void addMilk() {  
        System.out.println("加奶");  
    }  
}
public abstract class Dessert {  
    public abstract void show();  
}
  • 咖啡与甜点具体产品类
public class AmericanCoffee extends Coffee {  
    @Override  
    public String getName() {  
        return "美式咖啡";  
    }  
}
public class LatteCoffee extends Coffee {  
    @Override  
    public String getName() {  
        return "拿铁咖啡";  
    }  
}
public class Tiramisu extends Dessert{  
    @Override  
    public void show() {  
        System.out.println("提拉米苏");  
    }  
}
public class MatchaMousse extends Dessert{  
    @Override  
    public void show() {  
        System.out.println("抹茶慕斯");  
    }  
}
  • 具体工厂类
public class AmericanDessertFactory implements DessertFactory{  
    @Override  
    public Coffee createCoffee() {  
        return new AmericanCoffee();  
    }  
    @Override  
    public Dessert createDessert() {  
        return new MatchaMousse();  
    }  
}
public class ItalyDessertFactory implements DessertFactory{  
    @Override  
    public Coffee createCoffee() {  
        return new LatteCoffee();  
    }  
    @Override  
    public Dessert createDessert() {  
        return new Tiramisu();  
    }  
}
  • 测试类,只需要更改工厂类即可切换具体产品创建
    public static void main(String[] args) {  
//        创建意式风味工厂对象  
//        ItalyDessertFactory factory = new ItalyDessertFactory();  
        AmericanDessertFactory factory = new AmericanDessertFactory();  
//        点拿铁咖啡  
        Coffee coffee = factory.createCoffee();  
//        点提拉米苏  
        Dessert dessert = factory.createDessert();  
        System.out.println(coffee.getName());  
        dessert.show();  
    }
  • 类图![[Pasted image 20221229164038.png]]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言 文件处理2 程序环境和预处理

对比函数 sprintf(把一个格式化数据转化为字符串) sscanf (从一个字符串中读一个格式化数据) struct S {char arr[10];int age;float f; };int main() {struct S s { "hello", 20, 5.5f };//把这个转化为一个字符串s…

idea调试unity里面的lua代码

前言 本人一名java后端开发,看到前端同事调试lua代码无脑print,甚为鄙视,百度加实操写一份调试unity的lua脚本文档 操作 1.安装lua lua官网下载页面 最终下载页面 2.idea安装插件 emmylua 3.idea打开unity的lua脚本 idea->file->op…

【面试题】面试如何正确的介绍项目经验

大厂面试题分享 面试题库前端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库1、在面试前准备项目描述,别害怕,因为面试官什么都不知道面试官是人,不是神,拿到你的简历的时候…

ospf双向重发布,LSA优化综合

目录实验分析ip地址划分写公网缺省路由区域0公网MGRE搭建各个区域ospf的宣告改变ospf接口工作方式和更改接口优先级ospf多进程及双向重发布减少LSA的更新量1,减少特殊区域的LSA更新量2,骨干区域的优化域间汇总域外汇总防环nat的设置实验分析 如图实际的…

VS Code 为 Clang for MSVC 配置 cmake cmake tools

介绍 在windows平台上,由于平台API差异过大,一般为linux设计的项目(POSIX兼容)无法通过MSVC的编译,而是会报非常多的头文件错误。如果要修改,工程量将巨大。Windows平台上,主要有两个类POSIX兼容…

【JavaScript】事件--总结

千锋 1.Event 对象 代表事件的状态&#xff0c;比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。 div{width: 200px;height: 200px;background-color: yellow;} </style> <body><input type"text" id"username"&…

JavaScript 事件

文章目录JavaScript 事件HTML 事件常见的HTML事件JavaScript 可以做什么?JavaScript 事件 HTML 事件是发生在 HTML 元素上的事情。 当在 HTML 页面中使用 JavaScript 时&#xff0c; JavaScript 可以触发这些事件。 HTML 事件 HTML 事件可以是浏览器行为&#xff0c;也可以是…

babel做兼容处理 到底怎么使用?

1.背景 日常项目开发中总是避免不了对低版本浏览器做一些兼容处理&#xff0c;最常见的手段就是结合编译工具使用babel来处理一些语法的兼容&#xff0c;但是每次使用的时候其实Babel的配置和使用到的相关库总是云里雾里&#xff0c;网上的各种推荐方案眼花缭乱不知道到底应该…

自定义DotNetCore 项目模板

在进行代码开发时候&#xff0c;各自的团队或者公司都会有服务自己要求的项目代码模板&#xff0c;再创建新的项目时&#xff0c;都需要按照模板规范进行定义&#xff0c;NET支持自定义项目模板&#xff0c;这样在进行项目创建时就会高效很多。 官方参考文档&#xff1a;dotne…

软测复习01:软件测试概述

文章目录软件测试的目的软件测试的定义软件测试与软件开发软件测试发展软件测试的目的 基于不同的立场&#xff0c;存在着两种完全不同的测试目的 从用户的角度出发&#xff0c;希望通过软件测试暴露软件中隐藏的错误和缺陷&#xff0c;以考虑是否可接受该产品。从软件开发者的…

Java当中的定时器

目录 一、什么是定时器 二、Java当中的定时器 ①schedule()方法&#xff1a; ②TimerTask ​编辑 ③delay 三、实现一个定时器 前提条件: 代码实现: ①确定一个“任务”&#xff08;MyTask)的描述&#xff1a; ②schedule方法&#xff1a; ③需要一个计时器 属性…

MAT-内存泄漏工具使用

目录 一、MAT简介 1.1 MAT介绍 1.2 MAT工具的下载安装 二、使用MAT基本流程 2.1 获取HPROF文件 2.2 MAT主界面介绍 2.3 MAT中的概念介绍 2.3.1 Shallow heap 2.3.2 Retained Heap 2.3.3 GC Root 2.4 MAT中的一些常用的视图 2.4.1 Thread OvewView 2.4.2 Group 2.…

复杂工况下少样本轴承故障诊断的元学习

摘要&#xff1a;近年来&#xff0c;基于深度学习的轴承故障诊断得到了较为系统的研究。但是&#xff0c;这些方法中的大多数的成功在很大程度上依赖于大量的标记数据&#xff0c;而这些标记数据在实际生产环境中并不总是可用的。如何在有限的数据条件下训练出鲁棒的轴承故障诊…

线程状态到底是5种还是六种?傻傻分不清楚

目录 从操作系统层面上描述线程状态 从javaAPI层面上理解线程的6种状态 线程的状态转换. NEW --> RUNNABLE 1.RUNNABLE <--> WAITING 2.RUNNABLE <--> WAITING 3.RUNNABLE <--> WAITING 1.RUNNABLE <--> TIMED_WAITING 2.RUNNABLE <--&…

开源天气时钟项目删减和更新

开源天气时钟项目删减和更新&#x1f4cc;原项目开源地址&#xff1a;https://gitee.com/liuzewen/ESP8266-SSD1306-Watch-mini ✨本文只针对Arduino IDE平台代码进行删减和更新。 &#x1f4fa;按键菜单功能 &#x1f33c;天气时钟功能整体架构描述 代码中所使用的库&…

【MySQL】十,SQL执行流程

MySQL中的SQL执行流程 MySQL的查询流程 查询缓存 Server 如果在查询缓存中发现了这条 SQL 语句&#xff0c;就会直接将结果返回给客户端 如果没有&#xff0c;就进入到解析阶段&#xff08;MySQL 8.0 已经废弃了查询缓存功能&#xff09;。 解析器 在解析器中对 SQL 语句进行…

36、基于STM32的电子闹钟(DS1302)

编号&#xff1a;36 基于STM32的电子闹钟&#xff08;DS1302&#xff09; 功能描述&#xff1a; 本设计由STM32单片机液晶1602按键DS1302时钟模块声光报警模组成。 1、采用STM32F103最小系统。 2、利用DS1302芯片提供时钟信号 3、液晶1602实时显示年月日、时分秒、星期等信息…

java线程池原理

背景&#xff1a;为什么需要线程池java中的线程池是运用场景最多的并发框架&#xff0c;几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中&#xff0c;合理的使用线程池能够带来3个好处。降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消…

(1分钟了解)SLAM的七大问题:地图表示、信息感知、数据关联、定位与构图、回环检测、深度、绑架

编辑切换为居中添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;SLAM问题也被称为是CML问题。编辑切换为居中添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;编辑切换为居中添加图片注释&#xff0c;不超过 140 字&#xff08;可选&…

(JMLR-2019)NAS综述鼻祖-神经架构搜索:一项调查

神经架构搜索&#xff1a;一项调查 paper题目&#xff1a;Neural Architecture Search: A Survey paper是博世人工智能中心发表在JMLR 2019的工作 paper链接&#xff1a;地址 Abstract 过去几年&#xff0c;深度学习在图像识别、语音识别和机器翻译等各种任务上取得了显着进步…