设计模式—创建型模式之工厂模式

设计模式—创建型模式之工厂模式

工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。

简单工厂模式

比如我们有造车的工厂,来生产车,我们先定义一个抽象车产品:

//抽象车产品类
public abstract class AbstractCar { String engine;public abstract void run();
}

我们有两个具体的产品,货车和家用小汽车,都继承自抽象车:

//货车
public class Truck extends AbstractCar{public Truck() {this.engine = "货车引擎";}@Overridepublic void run() {System.out.println(this.engine+"--->正在运行");}
}
//家用小汽车
public class MiniCar extends AbstractCar{public MiniCar() {this.engine = "家用小汽车引擎";}@Overridepublic void run() {System.out.println(this.engine + "----------》正在运行");}
}

那我们的工厂可以如此定义:

public class MySimpleFactory {/*** 获取车* @param type* @return*/public AbstractCar newCar(String type){if("truck".equals(type)){return new Truck();}else if("mini".equals(type)){return new MiniCar();}return null;}
}

一般简单工厂生产的产品优先。

测试类如下:

public class SimpleFactoryTest {public static void main(String[] args) {MySimpleFactory factory = new MySimpleFactory();AbstractCar truck = factory.newCar("truck");AbstractCar mini = factory.newCar("mini");truck.run();mini.run();}
}

运行如下:

运行效果

缺点

**违反了开闭原则,扩展不易。**如果有大量的产品,会有大量的if else。

工厂方法模式

因为简单工厂模式,会出现大量的if else,并不能满足打开扩展、关闭修改的原则,我们希望,如果有扩展,直接扩展一个类就好,不区改动创造类型的代码,这样工厂方法模式就出现了。我们可以把工厂再进行抽象,把我们的工厂提升一个层次。

抽象类或者接口,就会有多个实现;有多实现 就会有多功能。

抽象工厂如下:

public abstract class AbstarctCarFactory {public abstract AbstractCar newCar();
}

我们的货车、小汽车,分别由不同的工厂来创建:

//货车工厂
public class TruckFactory extends AbstarctCarFactory {@Overridepublic AbstractCar newCar() {return new Truck();}
}
//小汽车工厂
public class MiniCarFactory extends AbstarctCarFactory {@Overridepublic AbstractCar newCar() {return new MiniCar();}
}

测试类如下:

public class FactoryMethodTest {public static void main(String[] args) {AbstarctCarFactory miniCarFactory = new MiniCarFactory();AbstractCar miniCar = miniCarFactory.newCar();miniCar.run();TruckFactory truckFactory = new TruckFactory();AbstractCar truck = truckFactory.newCar();truck.run();}
}

运行结果如下:

运行结果

这样,如果我们有新的类型,可以直接继承这个抽象工厂即可。

缺点

系统复杂度增加,可创建的品类单一。

抽象工厂模式

我们先来区分两个概念:

  • 产品等级:比如手机可以分为低配版手机、高配版手机;产品等级结构即产品的继承结构,如抽象类为手机,可以有拍照手机、游戏手机等等。
  • 产品族:产品可以分为手机、汽车等,这是产品族。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。

在车的产品基础上,我们又增加了新的产品,手机。

public abstract class AbstractPhone {//手机类型String type;public abstract void run();
}public class GamePhone extends AbstractPhone {public GamePhone() {this.type = "游戏手机";}@Overridepublic void run() {System.out.println(this.type + "正在运行了...");}
}public class MyPhotoPhoneFactory implements MyAbstarctFactory{@Overridepublic AbstractPhone newPhone() {return new PhotoPhone();}
}

如果我们想生产车和手机,我们可以定义抽象工厂:

public interface  MyAbstarctFactory {default AbstractCar newCar(){return null;}default AbstractPhone newPhone(){return null;}
}

生产手机的工厂分别为:

public class MyGamePhoneFactory implements MyAbstarctFactory{@Overridepublic AbstractPhone newPhone() {return new GamePhone();}
}
public class MyPhotoPhoneFactory implements MyAbstarctFactory{@Overridepublic AbstractPhone newPhone() {return new PhotoPhone();}
}

生产车的工厂分别为:

public class MyMiniCarFactory implements MyAbstarctFactory{@Overridepublic AbstractCar newCar() {return new MiniCar();}
}public class MyTruckCarFactory implements MyAbstarctFactory{@Overridepublic AbstractCar newCar() {return new Truck();}
}

测试类如下:

public class MyTest {public static void main(String[] args) {MyAbstarctFactory factory = new MyGamePhoneFactory();AbstractPhone abstractPhone = factory.newPhone();abstractPhone.run();factory = new MyMiniCarFactory();AbstractCar abstractCar = factory.newCar();abstractCar.run();}
}

运行如下:

运行结果

可以看到,我们在扩展时,都是新增类,而不是修改原有的方法。

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

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

相关文章

NSSCTF做题第十页(1)

[GXYCTF 2019]禁止套娃 看源代码也没什么东西&#xff0c;扫一下看看 发现了git泄露 话不多说直接开整 下载下来了 flag.php 还是代码审计 <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br>"; if(isset($_GET[exp])){ if (!preg_…

EPLAN_012#自定义导航器

关键字&#xff1a;设备导航器、端子排导航器、电缆导航器、设备列表导航器&#xff0c;树形结构&#xff08;导航器&#xff09; 正常情况下&#xff0c;eplan中的设备导航器是这个模样 如何在导航器中显示更多内容或者进行规划。&#xff08;比如下图中&#xff0c;可以显示其…

Spring Cloud之ElasticSearch的学习【详细】

目录 ElasticSearch 正向索引与倒排索引 数据库与elasticsearch概念对比 安装ES、Kibana与分词器 分词器作用 自定义字典 拓展词库 禁用词库 索引库操作 Mapping属性 创建索引库 查询索引库 删除索引库 修改索引库 文档操作 新增文档 查找文档 修改文档 全量…

IP应用场景API的反欺诈潜力:保护在线市场不受欺诈行为侵害

前言 在数字化时代&#xff0c;网络上的商业活动迅速增长&#xff0c;但与之同时&#xff0c;欺诈行为也在不断演化。欺诈者不断寻找新方法来窃取个人信息、进行金融欺诈以及实施其他不法行为。为了应对这一威胁&#xff0c;企业和组织需要强大的工具&#xff0c;以识别和防止…

项目文章 | CUTTag助力解析水稻白叶枯病菌Sigma因子70 RpoD的致病作用

发表单位&#xff1a;南京农业大学和江苏省农业科学院植物保护研究所 期 刊&#xff1a;Journal of Integrative Agriculture&#xff08;IF:4.8&#xff09; 发表日期&#xff1a;2023年10月18日 2023年南京农业大学和江苏省农业科学院植物保护研究所研究团队在期刊Jo…

k8s replicaSet,deployment 学习笔记

文章目录 replicaSet 和 deployment 两者的关系。创建滚动更新回滚 replicaSet 和 deployment 两者的关系。 在 Kubernetes 中&#xff0c;ReplicaSet 和 Deployment 都是用来确保某种 Pod 的副本数目。但是&#xff0c;ReplicaSet 和 Deployment 是有差别的&#xff0c;二者的…

C++标准模板(STL)- 类型支持 (类型特性,is_pointer,is_lvalue_reference,is_rvalue_reference)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实…

【JVM】类的声明周期(加载、连接、初始化)

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 JVM 一、类的声明周期&#xff08;加载阶段…

HTML5+CSS3+Vue小实例:路飞出海的动画特效

实例:路飞出海的动画特效 技术栈:HTML+CSS+Vue 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&…

第N个斐波那契数列

第N个斐波那契数列 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class Solution { public:int tribonacci(int n) {int a[4]{0,1,1,2};if(n<4) return a[n];int kn-3;for(int i0; i<k;i){int tmpa[3];a[3]a[1]a[2]a[3];//不是【0】开始&…

Python对象(Object)与类型(Type)的关系

Object与Type 1、Object与Type概述2、Object与Type的关系 1、Object与Type概述 对象&#xff08;Object&#xff09;和类型&#xff08;Type&#xff09;是Python中两个最最基本的概念&#xff0c;它们是构筑Python语言大厦的基石 所有的数据类型&#xff0c;值&#xff0c;变…

【网络安全 --- 文件上传靶场练习】文件上传靶场安装以及1-5关闯关思路及技巧,源码分析

一&#xff0c;前期准备环境和工具 1&#xff0c;vmware 16.0安装 若已安装&#xff0c;请忽略 【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;提供资源&#xff09;-CSDN博客文章浏览阅读186次&#xff0c;点赞9次&#xff0c;收藏2次。【网络安全 --- 工…

Kubernetes - Ingress HTTP 升级 HTTPS 配置解决方案(新版本v1.21+)

之前我们讲解过 Kubernetes - Ingress HTTP 搭建解决方案&#xff0c;并分别提供了旧版本和新版本。如果连 HTTP 都没搞明白的可以先去过一下这两篇 Kubernetes - Ingress HTTP 负载搭建部署解决方案_放羊的牧码的博客-CSDN博客Kubernetes - Ingress HTTP 负载搭建部署解决方案…

【Go入门】GO流程与函数介绍(代码运行逻辑控制)

流程和函数 这小节我们要介绍Go里面的流程控制以及函数操作。 流程控制 流程控制在编程语言中是最伟大的发明了&#xff0c;因为有了它&#xff0c;你可以通过很简单的流程描述来表达很复杂的逻辑。Go中流程控制分三大类&#xff1a;条件判断&#xff0c;循环控制和无条件跳…

Mac/Linux类虚拟机_CrossOver虚拟机CrossOver 23.6正式发布2024全新功能解析

CodeWeivers 公司于今年 10 月发布了 CrossOver 23.6 测试版&#xff0c;重点添加了对 DirectX 12 支持&#xff0c;从而在 Mac 上更好地模拟运行 Windows 游戏。 该公司今天发布新闻稿&#xff0c;表示正式发布 CrossOver 23 稳定版&#xff0c;在诸多新增功能中&#xff0c;最…

Mybatis-Plus通用枚举功能 [MyBatis-Plus系列] - 第493篇

历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 S…

3D LUT 滤镜 shader 源码分析

最近在做滤镜相关的渲染学习&#xff0c;目前大部分 LUT 滤镜代码实现都是参考由 GPUImage 提供的 LookupFilter 的逻辑&#xff0c;整个代码实现不多。参考网上的博文也有各种解释&#xff0c;参考了大量博文之后终于理解了&#xff0c;所以自己重新整理了一份&#xff0c;方便…

JMeter的使用——傻瓜式学习【中】

目录 前言 1、JMeter参数化 1.1、什么是参数化 1.2、用户定义的变量 1.2.1、什么时候使用用户定义的变量 1.2.2、使用“用户定义的变量”进行参数化的步骤&#xff1a; 1.2.3、案例 1.3、用户参数 1.3.1、什么时候使用用户参数&#xff1f; 1.3.2、使用“用户参数”进…

VScode 调试 linux内核

VScode 调试 linux内核 这里调试的 linux 内核是通过 LinuxSD卡(rootfs)运行的内核 gdb 命令行调试 编辑 /home/tyustli/.gdbinit 文件&#xff0c;参考 【GDB】 .gdbinit 文件 set auto-load safe-path /home/tyustli/code/open_source/kernel/linux-6.5.7/.gdbinit在 lin…

PFAF-Net

I 1 _1 1​和I 2 _2 2​是多模态图像&#xff0c;I F _F F​是融合图像。FT 1 _1 1​是基于空间注意力的融合&#xff0c;FT 2 _2 2​是基于通道注意力的融合 作者未提供代码