【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录

    • 定义
    • 简单工厂模式
      • 案例 | 代码
        • Phone顶层接口设计
        • Meizu品牌类
        • Xiaomi品牌类
        • PhoneFactory工厂类
        • Customer 消费者类
    • 工厂方法模式
      • 案例 | 代码
        • PhoneFactory工厂类
    • Java高级特性---工厂模式与反射的高阶玩法
        • 方案:反射+工厂模式
    • 总结

其实工厂模式就是用一个代理类帮你创建管理对象,你就不用在代码层面去不断new对象的使用了。

创建对象和调用对象两者之间会解耦!

定义

工厂模式有三种:

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

简单工厂模式

简单工厂模式也叫静态工厂模式。

举个例子:你要去买一台手机,你不用关心手机是怎么生产出来的,里面的零件具体又是怎么制造的,这些通通都交给工厂去处理,你尽管去买手机就好了。

image-20240705131418461

案例 | 代码

Phone顶层接口设计
/*** @author linghu* @date 2024/7/5 11:08*/
public interface Phone {void getBrand();
}
Meizu品牌类
/*** @author linghu* @date 2024/7/5 11:09*/
public class Meizu implements Phone{@Overridepublic void getBrand() {System.out.println("魅族");}
}
Xiaomi品牌类
/*** @author linghu* @date 2024/7/5 12:35*/
public class Xiaomi implements Phone{@Overridepublic void getBrand() {System.out.println("小米");}
}
PhoneFactory工厂类

这个是简单工厂模式,又叫静态工厂,所以方法自然是静态的!而且这个工厂类负责帮我们创建对象,并且返回对象!

在这里我们可以先用硬编码的方式:

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getPhone(String phone){if ("小米".equals(phone)){return new Xiaomi();} else if ("魅族".equals(phone)) {return new Meizu();}else {return null;}}
}
Customer 消费者类

这个类就类似一个客户端的作用把。

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) {PhoneFactory.getPhone("小米").getBrand();PhoneFactory.getPhone("魅族").getBrand();}
}

image-20240705132326792

工厂方法模式

工厂方法模式就是在上面简单工厂模式的基础上做了一些修改,具体的做法就是为每种不同品牌的手机都创建一个工厂独立生产。

image-20240705140352151

案例 | 代码

如上,其他代码都不变,变化的部分是工厂那部分!

PhoneFactory工厂类

首先修改一下PhoneFactory工厂类,将:

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getPhone(String phone){if ("小米".equals(phone)){return new Xiaomi();} else if ("魅族".equals(phone)) {return new Meizu();}else {return null;}}
}

修改为:

/*** @author linghu* @date 2024/7/5 12:35*/
public interface PhoneFactory {Phone getPhone();
}

新增的两个工厂类:

/*** @author linghu* @date 2024/7/5 14:09*/
public class MeizuFactory implements PhoneFactory{@Overridepublic Phone getPhone() {return new Meizu();}
}
/*** @author linghu* @date 2024/7/5 14:08*/
public class XiaomiFactory implements PhoneFactory{@Overridepublic Phone getPhone() {return new Xiaomi();}
}

Customer 消费者类:

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();Phone xiaomi=new XiaomiFactory().getPhone();Phone meizu=new MeizuFactory().getPhone();xiaomi.getBrand();meizu.getBrand();}
}

image-20240705142134386

Java高级特性—工厂模式与反射的高阶玩法

我们先回顾一下上面的工厂模式用法,列举一下会发现:

  • 简单工厂模式的局限性在于:如果我们扩充手机的品牌,就会违反 开闭原则
  • 工厂方法模式的局限性在于:我们扩充手机品牌需要不断new更多对象,这是耦合的最大元凶!!
方案:反射+工厂模式

PhoneFactory工厂类

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getInstance(String origin) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> cls = Class.forName("com.linghu.factory." + origin);Phone brand=(Phone)cls.newInstance();return brand;}
}

Customer 消费者类

这个时候我们无需再new更多对象了,也不用写死了:

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();
//        Phone xiaomi=new XiaomiFactory().getPhone();
//        Phone meizu=new MeizuFactory().getPhone();
//        xiaomi.getBrand();
//        meizu.getBrand();PhoneFactory.getInstance("Xiaomi").getBrand();}
}

image-20240705161002362

输入类名以后,反射创建对象,再通过工厂返回相关对象!!

总结

第一个静态工厂模式:在实际去开发中会发现比较常用,尽管上面讲了不符合(面向对象)OOP原则。
第二个工厂方法模式:不修改工厂类的前提,也就是说不修改已有类,实现对扩展是开发,对修改关闭。

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

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

相关文章

Linux x86_64平台指令替换函数 text_poke_smp/bp

文章目录 前言一、text_poke_early1.1 text_poke_early简介1.2 用途 二、text_poke_smp2.1 简介2.1.1 text_poke_smp函数2.2.2 stop_machine_text_poke简介2.2.3 text_poke函数 2.2 用途 三、text_poke_smp 内核hook 前言 Linux x86_64平台指令替换函数有两种类型&#xff1a;…

万界星空科技机械加工行业MES解决方案

机械加工行业作为制造业的重要组成部分&#xff0c;面临着生产效率、成本控制和产品质量提升等多重挑战。为了应对这些挑战&#xff0c;引入并实施制造执行系统&#xff08;MES&#xff09;成为了行业的必然选择。本文将详细介绍一种针对机械加工行业的MES解决方案&#xff0c;…

【Docekr】容器自动重启/取消自动重启

Docekr 容器自动重启/取消自动重启 文章目录 Docekr 容器自动重启/取消自动重启Docker 重启模式Docker 更新容器 Docker 重启模式 Docker的restart可以控制容器的重启模式&#xff0c;其有以下几个值&#xff1a; # 默认策略&#xff0c;容器退出时不重启容器 --restartno# 在…

用MySQL+node+vue做一个学生信息管理系统(二):创建MySQL数据表、创建HTML用户列表页面

MySQL代码 CREATE DATABASE students;USE students;CREATE TABLE student( id INT COMMENT 学号, name VARCHAR(32) COMMENT 姓名, sex VARCHAR(8) COMMENT 性别, class VARCHAR(64) COMMENT 班级 )SHOW TABLES;下面介绍一下Vue框架的element-ui的使用方法&#xff0c;这里就不…

常用排序算法_06_归并排序

1、基本思想 归并排序采用分治法 (Divide and Conquer) 的一个非常典型的应。归并排序的思想就是先递归分解数组&#xff0c;再合并数组。归并排序是一种稳定的排序方法。 将数组分解最小之后&#xff08;数组中只有一个元素&#xff0c;数组有序&#xff09;&#xff1b;然后…

Spring Boot + liteflow 居然这么好用!实战

在我们的日常开发中&#xff0c;经常会遇到一些需要串行或并行处理的复杂业务流程。 那我们该如何利用Spring Boot结合liteflow规则引擎来简化我们的业务流程 先看一个实战案例&#xff01;&#xff01; 在电商场景下&#xff0c;当订单完成后&#xff0c;我们需要同时进行积…

go 为什么是抢占式调度

GMP 模型 gmp模型是 golang 中用于调度管理 goroutine 的调度器。 调度器的发展史 在 Go 语言中&#xff0c;Goroutine 早期是没有设计成抢占式的&#xff0c;早期 Goroutine 只有读写、主动让出、锁等操作时才会触发调度切换。 这样有一个严重的问题&#xff0c;就是垃圾回…

鸿蒙笔记导航栏,路由,还有axios

1.导航组件 导航栏位置可以调整&#xff0c;导航栏位置 Entry Component struct t1 {build() {Tabs(){TabContent() {Text(qwer)}.tabBar("首页")TabContent() {Text(发现内容)}.tabBar(发现)TabContent() {Text(我的内容)}.tabBar("我的")}// 做平板适配…

文心一言:探索AI写作的新境界

在人工智能飞速发展的今天&#xff0c;AI写作助手已经成为许多写作者、内容创作者和营销专家的重要工具。"文心一言"作为一个先进的AI写作平台&#xff0c;以其强大的语言理解和生成能力&#xff0c;为用户提供了从文本生成到编辑、优化等一系列服务。本文将介绍如何…

【Springer出版 | EI稳定检索】第五届物联网、人工智能与机械自动化国际学术会议 (IoTAIMA 2024,7月19-21)

由浙江工业大学主办&#xff0c;第五届物联网、人工智能与机械自动化国际学术会议 (IoTAIMA 2024) 将于2024年7月19-21日在浙江杭州召开。 会议旨在为从事物联网、人工智能与机械自动化的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学…

深入Django(七)

Django的数据库迁移系统 引言 在前六天的教程中&#xff0c;我们介绍了Django的基本概念、模型、视图、模板、URL路由和表单系统。今天&#xff0c;我们将讨论Django的数据库迁移系统&#xff0c;它是管理和跟踪数据库变化的关键组件。 Django数据库迁移概述 Django的数据库…

基于java+springboot+vue实现的药店管理系统(文末源码+Lw)285

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;药品信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

论文创新的几种思路

选题是论文创新的基石&#xff0c;它决定了研究的方向和深度。一个新颖的选题不仅能够吸引读者和评审的注意&#xff0c;还能为学术界带来新的视角和思考。选题创新要求研究者具有敏锐的洞察力&#xff0c;能够识别和捕捉到那些尚未被充分探索或有待深入研究的问题。 选题创新…

SSM家庭理财个人理财系统-JAVA【数据库设计、源码、开题报告】

第一章 绪论 1.1 课题背景、目的及意义 从 20 世纪末以来&#xff0c;在全球经济日趋一体化的背景之下&#xff0c;中国经济也得到了飞速的发展&#xff0c;家庭收入也快速增长。居民的消费结构发生了巨大变化&#xff0c;购置房产、旅游、汽车消费、教育等成为居民消费重点。…

一维前缀和的实现

这是C算法基础-基础算法专栏的第十一篇文章&#xff0c;专栏详情请见此处。 引入 我们用朴素做法求一维数组的区间和时&#xff0c;一般是从前向后循环累加&#xff0c;它的时间复杂度为&#xff0c;当求区间和的次数过多&#xff0c;则会有超时的可能&#xff0c;那有没有时间…

算法设计练笔

T1、给定由n个整数&#xff08;可能为负数&#xff09;组成的序列a1,a2,...,an&#xff0c;求该序列子段和的最大值。当所有整数均为负数时&#xff0c;其最大子段和为0。 【输入】 第一行一个整数&#xff0c;表示n的值, 1<n<100; 第二行n个整数&#xff0c;表示a1,a2,.…

ubuntu 查看联网配置

在Ubuntu中&#xff0c;你可以使用多种命令来查看联网配置。以下是一些常用的方法和命令&#xff1a; 查看网络接口配置&#xff1a; 使用 ip 命令可以查看网络接口的配置信息&#xff0c;包括IP地址、子网掩码等。 ip addr show或者&#xff0c;你也可以使用传统的 ifconfig 命…

【Unity URP】通过代码动态添加URP渲染通道RendererFeature

URP的渲染通道RendererFeature可以很方便的实现一些渲染问题,比如渲染顺序问题,遮挡后的材质替换等等。 那么我们如何通过代码来动态添加和修改呢? 首先我们需要获取到当前的URP配置文件,在对配置文件进行添加 1.通过反射获取当前UniversalRendererData 我们通过Graphic…

如何快速上手文心一言指令

快速上手文心一言指令&#xff0c;可以遵循以下步骤和要点&#xff0c;以确保高效且准确地与文心一言进行交互&#xff1a; 一、了解文心一言基础 1. 文心一言简介 文心一言是百度研发的人工智能模型&#xff0c;用户可以通过输入指令与其进行互动&#xff0c;提出问题或要求…

中国移动中国联通中国电信数字化转型营销销售讲师培训老师讲授AIGC大模型人工智能5G云算力网络云网终端AIGC人工智能宽带政企物联网专线 IDC智慧城市

唐兴通 数字化商业创新顾问、新媒体营销专家、数字化销售增长教练、沃顿商学院演讲嘉宾。全球创新增长战略大家EM罗杰斯&#xff08;创新的扩散&#xff09;、杰弗里摩尔&#xff08;跨越鸿沟&#xff09;、亨利切萨布鲁夫&#xff08;开放式创新&#xff09;在中国合作者。《…