当前位置: 首页 > news >正文

简单工厂模式~

我们以生产手机作为应用场景展开讲解!

手机是一个抽象的概念,它包含很多的品牌,例如华为,苹果,小米等等,因此我们可将其抽象为一个接口,如下所示:

public interface tel {void produce();
}

苹果手机作为手机的实现类之一实现手机的接口:

public class appleTel implements tel{@Overridepublic void produce() {System.out.println("苹果手机");}
}

华为手机也是如此

public class huaweiTel implements tel{@Overridepublic void produce() {System.out.println("华为手机");}
}

客户端代码:

public class test {public static void main(String[] args) {//生产苹果手机---创建对应的实例对象tel tel=new appleTel();tel.produce();//生产华为手机---创建对应的实例对象tel tel1=new huaweiTel();tel1.produce();}
}

如上所示为客户端,每生产一个产品就要实现创建实现类的实例化对象,这种方式既包含对象的创建也包含对象的实现,其耦合度很高,为了将对象的创建与使用分离隐藏具体实现细节,提高代码的灵活性,我们引入了工厂模式

如下所示我们创建工厂类:

它的作用是将对象的创建逻辑封装起来,其中我们通过if-else语句对客户端传递的参数进行判断,创建对应的实现类的实例化对象,

public class telfactory {public tel create(String name){if(name.equals("华为")){return new huaweiTel();} else if(name.equals("苹果")){return new appleTel();}else {return null;}}
}

客户端代码修改如下所示:

与上述相比,我们将具体对象的创建过程隐藏在工厂类中客户端只需关心所需对象的接口,而无需关心具体的实现细节。这样可以保护对象的具体实现细节提高代码的安全性

public class test {public static void main(String[] args) {//工厂模式---只需要创建工程类的实例化对象,其实现类的对象创建过程在工厂类中完成telfactory telfactory=new telfactory();telfactory.create("苹果").produce();telfactory.create("华为").produce();}
}

上述我们是在工厂类中通过if-else语句进行判断后创建对应的实现类实例化对象,这种方式有很多缺点,它不符合开闭原则,假设未来我们有了更多的实现类,那么必须修改工厂类中的if-else,代码的灵活性并不高。

对此,我们可以再进行优化,在工厂类中我们的判断逻辑不在具体到每个实现类上,而是只需要判断客户端给定的类名通过反射创建的实例对象是否可以上转型成我们的接口类型。

public class telfactory {public tel create(String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//根据在客户端给定的类名,返回一个Class对象,该对象表示与客户端指定类名对应的类,再调用newInstance(),创建该类的一个实例对象。再将其通过上转型转化为tel接口类型if(!(null==classname||"".equals(classname))) {return (tel) Class.forName(classname).newInstance();}return null;}
}

客户端只需要指定类名,但是需要注意传入的必须是全类名

public class test {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {telfactory telfactory=new telfactory();//传入全类名,以便通过反射创建对应的实现类的实例化对象telfactory.create("com.wjr.demo1.telFactory.appleTel").produce();telfactory.create("com.wjr.demo1.telFactory.huaweiTel").produce();}
}

上述对工厂类中的代码进行了优化,但客户端需要传入的是字符串的全类名,而且只有当运行之后我们才知道传入的类名是否有问题,这显然不利于我们测试,因此我们可以修改客户端传入的参数类型,通过泛型限定限定传入的类必须为实现当前接口,假设我们在客户端传入的类不符合,编译器也会及时的报错,以便我们修改和检查

public class telfactory {public tel create(Class <? extends tel> clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//通过泛型限定传入的类型必须是tel的实现类if(!(null==clazz||"".equals(clazz))) {return clazz.newInstance();}return null;}
}
public class test {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {telfactory telfactory=new telfactory();telfactory.create(com.wjr.demo1.telFactory.appleTel.class).produce();telfactory.create(com.wjr.demo1.telFactory.huaweiTel.class).produce();}
}

相关文章:

简单工厂模式~

我们以生产手机作为应用场景展开讲解&#xff01; 手机是一个抽象的概念&#xff0c;它包含很多的品牌&#xff0c;例如华为&#xff0c;苹果&#xff0c;小米等等&#xff0c;因此我们可将其抽象为一个接口&#xff0c;如下所示&#xff1a; public interface tel {void pro…...

基于Java的会员管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

数据结构 图 并查集 遍历方法 最短路径算法 最小生成树算法 简易代码实现

文章目录 前言并查集图遍历方法广度优先遍历深度优先遍历 最小生成树算法Kruskal算法Prim算法 最短路径算法Dijkstra算法BellmanFord算法FloydWarshall算法 全部代码链接 前言 图是真的难&#xff0c;即使这些我都学过一遍&#xff0c;再看还是要顺一下过程&#xff1b;说明方…...

idea Springboot 教师标识管理系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 教师标识管理系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统 具有完整的源代码和数据库&…...

2023-9-30 JZ36 二叉搜索树与双向链表

题目链接&#xff1a;二叉搜索树与双向链表 import java.util.*; /** public class TreeNode {int val 0;TreeNode left null;TreeNode right null;public TreeNode(int val) {this.val val;}} */ public class Solution {TreeNode pre null;public TreeNode Convert(Tree…...

在windows的ubuntu LTS中安装及使用EZ-InSAR进行InSAR数据处理

EZ-InSAR&#xff08;曾被称为MIESAR&#xff0c;即Matlab界面用于易于使用的合成孔径雷达干涉测量&#xff09;是一个用MATLAB编写的工具箱&#xff0c;用于通过易于使用的图形用户界面&#xff08;GUI&#xff09;进行干涉合成孔径雷达&#xff08;InSAR&#xff09;数据处理…...

腾讯mini项目-【指标监控服务重构】2023-08-25

今日已办 traefik proxy jaeger Prometheus prometheus | Prometheus 配置完依然无法实现 web-url的前缀访问【待解决】 Set span storage type : elasticsearch services:elasticsearch:image: elasticsearch:7.17.12container_name: elasticsearchnetworks:- backend # …...

数据挖掘(1)概述

一、数据仓库和数据挖掘概述 1.1 数据仓库的产生 数据仓库与数据挖掘&#xff1a; 数据仓库和联机分析处理技术(存储)。数据挖掘&#xff1a;在大量的数据中心挖掘感兴趣的知识、规则、规律、模式、约束(分析)。数据仓库用于决策分析&#xff1a; 数据仓库&#xff1a;是在数…...

YApi Pro

1.介绍 说明&#xff1a;YApi Pro 是一款高效、易用、功能强大的 API 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。它可以帮助开发者轻松创建、发布、维护 API&#xff0c;同时为用户提供了优秀的交互体验&#xff0c;开发人员可以更加高效地完…...

AUTOSAR RTE介绍(更新版230925)

RTE是什么 AUTOSAR RTE(Run Time Environment)实现了AUTOSAR系统中的虚拟功能总线(VFB),提供了SWC(Software Component)之间的访问接口和SWC对于BSW资源的访问接口。RTE为SWC中的Runnable提供与其他SWC或者BSW模块通信的接口,RTE将Runnable映射到OS Task中,并且管理Runna…...

深度学习笔记_1、定义神经网络

1、使用了PyTorch的nn.Module类来定义神经网络模型;使用nn.Linear来创建全连接层。(CPU) import torch.nn as nn import torch.nn.functional as F from torchsummary import summary# 定义神经网络模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()…...

【Java 进阶篇】MySQL 事务详解

在数据库管理中&#xff0c;事务是一组SQL语句的执行单元&#xff0c;它们被视为一个整体。事务的主要目标是保持数据库的一致性和完整性&#xff0c;即要么所有SQL语句都成功执行&#xff0c;要么所有SQL语句都不执行。在MySQL中&#xff0c;事务起到了非常重要的作用&#xf…...

Spring修炼之旅(3)自动装配与注解开发

一、自动装配说明 1.1概述 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean。 1.2装配机制 Spring中bean有三种装配机制&#xff0c;分别是&#xff1a; 在xml中显式配置&#xff1b; 在java中显式配置&#xff1b; 隐式…...

嵌入式Linux应用开发-基础知识-第十六章GPIO和Pinctrl子系统的使用

嵌入式Linux应用开发-基础知识-第十六章GPIO和Pinctrl子系统的使用 第十六章 GPIO 和 Pinctrl 子系统的使用16.1 Pinctrl 子系统重要概念16.1.1 引入16.1.2 重要概念16.1.3 示例16.1.4 代码中怎么引用pinctrl 16.2 GPIO子系统重要概念16.2.1 引入16.2.2 在设备树中指定引脚16.2…...

Ubuntu系统下使用apt-get安装Mysql8

记录一下在Ubuntu20.04 64位系统下面使用apt-get方式安装mysql8关系型数据库 Centos下使用yum安装Mysql8&#xff08;Mysql5.7&#xff09;以及常见的配置和使用 首先肯定是检查下当前Ubuntu系统是否已经安装过mysql数据库 一般拿到新的云服务器是没有安装的 rootmyw:~# whe…...

jenkins联动显示或隐藏参数

1. 添加组件 Active Choices Plug-in 如jenkins无法联网&#xff0c;可在以下两个地址中下载插件&#xff0c;然后放到/home/jenkins/.jenkins/plugin下面重启jenkins即可 Active Choices Active Choices | Jenkins plugin 2. 效果如下&#xff1a; sharding为空时&#xf…...

Error: Activity class {xxx.java} does not exist

git切换到不同的branch之后&#xff0c;报下面的错误&#xff1a; Error: Activity class {xxx.java} does not exist 解决方案&#xff1a; 首先clean 然后会删除build目录 然后点击&#xff1a;Invalidate Caches Android Studio重启&#xff0c;然后重新build即可。...

保护模式阶段测试-模拟3环0环调用

保护模式阶段测试-模拟3环0环调用 最近又复习了一下保护模式相关的内容&#xff0c;然后打算搞个能够把段页的大部分知识能够串联起来的测试代码 最终想到的一个项目如下&#xff1a; 三环部分&#xff1a; 0.编写一个函数读取高2g的地址内容 1.通过设备通信到0环告诉0环我新…...

Dart笔记:stream_channel 包用法

标题1 标题2 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133426961 【介绍】stream_channel是一个用…...

Java进阶必会JVM-深入浅出Java虚拟机

系列文章目录 送书第一期 《用户画像&#xff1a;平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 送书第二期 《Spring Cloud Alibaba核心技术与实战案例》 送书第三期 《深入浅出Java虚拟机》 文章目录 系列文章目录前言一、推荐书籍二…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...