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

设计模式之工厂模式(Factory)

任何可以产生对象的方法或类,都可以称为工厂。

下面的代码定义了Car这种交通工具:

public class Car {public void go() {System.out.println("Car go wuwuwuwuw....");}
}

然后在main函数里面想要调用调用Car的go方法,就需要new一个car对象,然后调用

public class Main {public static void main(String[] args) {Car m = new Car();m.go();}
}

如果又来了一个飞机,你想开飞机,又得在main函数里面,new一个Plane

public class Plane {public void go() {System.out.println("plane flying shushua....");}
}
public class Main {public static void main(String[] args) {// Car m = new Car();Plane m = new Plane();m.go();}
}

main函数的逻辑会改来改去

可以引入接口,简单多态的应用,car和plane都去实现Moveable这个接口

public interface Moveable {void go();
}
public class Car implements  Moveable {public void go() {System.out.println("Car go wuwuwuwuw....");}
}
public class Plane implements Moveable {public void go() {System.out.println("plane flying shushua....");}
}
public class Main {public static void main(String[] args) {Moveable m = new Car(); // 简单多态应用m.go();}
}

通过实现Moveable接口,做到了可以任意定制各种交通工具,只需要实现Moveable接口就行

1.简单工厂 工厂方法(Factory Method) --> 每种产品都对应一个工厂
创建一个工厂类,里面生产Car,Plane和Broom,可扩展性不好,有新的交通工具都得加,要定制的话,
所有的代码都写到了一个类里面

/*** 简单工厂的可扩展性不好*/
public class SimpleVehicleFactory {public Car createCar() {//before processing 可以加一些前置操作return new Car();}public Broom createBroom() {return new Broom();}// Plane...
}

可以给Car,Plane分别创建工厂,每个工厂里面可以做任意的定制,代码隔离开了 --> 通过xxxFactory做到了任意定制生产过程

public class CarFactory {public Moveable create() {System.out.println("a car created!");return new Car();}
}
public static void main(String[] args) {Moveable m = new CarFactory().create();m.go();
}

2.静态工厂
单例也是一种工厂,也被人称为静态工厂。

4.抽象工厂
如何任意扩展产品族?

public class Car{public void go() {System.out.println("Car go wuwuwuwuw....");}
}
public class AK47 {public void shoot() {System.out.println("tututututu....");}
}
public class Bread {public void printName() {System.out.println("wdm");}
}

有个人开着Car,拿着AK47,tututu,还吃着面包,客户端代码(使用这些类的代码),可能会像下面这样写,但是
如果来了一个人是魔法世界的人,骑得是扫帚,武器是魔法棒,吃的是蘑菇,你的客户端代码就又得重新写
Car,AK47,面包,是一个产品族
扫帚,魔法棒,蘑菇又是一个产品族
有没有一种方法,可以任意选择产品族,客户端代码不用改? --> 抽象工厂

public class Main {public static void main(String[] args) {Car car = new Car();car.go();AK47 ak47 = new AK47();ak47.shoot();Bread bread = new Bread();bread.printName();}
}

定义一个抽象工厂类: AbastractFactory可以生产一些列的产品,Food Vehicle Weapon

public abstract class AbastractFactory {abstract Food createFood();abstract Vehicle createVehicle();abstract Weapon createWeapon();
}

定义三个抽象类:

//交通工具
public abstract class Vehicle { //interfaceabstract void go();
}
//武器
public abstract class Weapon {abstract void shoot();
}
//食物
public abstract class Food {abstract void printName();
}

Car,AK47,Bread分别实现上面的抽象类

public class Car extends Vehicle{public void go() {System.out.println("Car go wuwuwuwuw....");}
}
public class AK47 extends Weapon{public void shoot() {System.out.println("tututututu....");}
}
public class Bread extends Food{public void printName() {System.out.println("wdm");}
}

Broom,MagicStick,MushRoom分别实现上面的抽象类

public class Broom extends Vehicle{public void go() {System.out.println("Car go wuwuwuwuw....");}
}
public class MagicStick extends Weapon{public void shoot() {System.out.println("diandian....");}
}
public class MushRoom extends Food{public void printName() {System.out.println("dmg");}
}

定义具体的ModernFactory:

public class ModernFactory extends AbastractFactory {@OverrideFood createFood() {return new Bread();}@OverrideVehicle createVehicle() {return new Car();}@OverrideWeapon createWeapon() {return new AK47();}
}

定义具体的MagicFactory:

public class MagicFactory extends AbastractFactory {@OverrideFood createFood() {return new MushRoom();}@OverrideVehicle createVehicle() {return new Broom();}@OverrideWeapon createWeapon() {return new MagicStick();}
}

AbastractFactory可以生产一些列的产品,Food Vehicle Weapon
定义一个ModernFactory,继承自AbastractFactory,现代的工厂可以生产Car,AK47,Bread(分别继承自Vehicle Weapon Food)
定义一个MagicFactory,也继承自AbastractFactory,魔法工厂可以生产Broom,MagicStick,MushRoom(分别继承自Vehicle Weapon Food)

一共有:抽象的工厂,具体的工厂,抽象的产品,具体的产品
在这里插入图片描述
在Main方法里面就只需要创建具体的工厂,然后调用方法就行,不用像之前,创建各种不同的对象之后再调用对应的方法:

public class Main {public static void main(String[] args) {AbastractFactory f = new ModernFactory(); // 如果是魔法世界的人,只需要该这一行代码就行,new MagicFactory(),非常方便Vehicle c = f.createVehicle();c.go();Weapon w = f.createWeapon();w.shoot();Food b = f.createFood();b.printName();}
}

探讨: 这里Vehicle类,用的是抽象类,只有一个抽象方法,是不是用接口也行?就像前面的Moveable一样? --> 形容词用接口,名词用抽象类

工厂方法和抽象工厂比较:
工厂方法方便在产品上进行扩展,有新的产品来了,只需要加新的xxxFactory就行,如果想要加新的族,就比较麻烦
如果是产品一族上进行扩展,抽象工厂就比较方便,只需要加具体的工厂就行(例如加火星工厂),但是要加的产品就比较麻烦,抽象工厂得加方法,具体工厂也得加方法
例如要加衣服这个产品,就需要在抽象工厂里面加creat衣服的方法,后面的具体工厂也得加

工厂方法: 添加产品维度方便
抽象工厂: 产品一族扩展方便

有没有一种方法,加新的产品和扩展一族产品比较方便呢? --> Spring bean 工厂

相关文章:

设计模式之工厂模式(Factory)

任何可以产生对象的方法或类,都可以称为工厂。 下面的代码定义了Car这种交通工具: public class Car {public void go() {System.out.println("Car go wuwuwuwuw....");} }然后在main函数里面想要调用调用Car的go方法,就需要new一个car对象&…...

2023/11/6 JAVA学习

处理编译异常的两种方法 第一种 第二种 问题比较容易犯,编译时异常...

Android-JobService

JobService 这里写目录标题 JobService一、API详解1 onStartJob2 onStopJob 二、onStartJob | onStopJob 返回值case 1case 2case 3 ref: 深入理解JobScheduler与JobService的使用 - 掘金 (juejin.cn) (28条消息) JobService的使用介绍_TechMerger的博客-CSDN博客 (28条消息) J…...

GraphQL入门与开源的GraphQL引擎Hasura体验

背景 Hasura 是一个开源的 GraphQL 引擎,它可以帮助开发人员快速构建和部署现代应用程序的后端。它提供了一个自动化的 GraphQL API ,可以直接连接到现有的数据库,并提供实时数据推送和订阅功能。 Hasura 团队总部位于印度。 下载安装 脚本…...

Javascript知识点详解:this关键字的指向问题

目录 this 关键字 涵义 实质 使用场合 使用注意点 避免多层 this 避免数组处理方法中的 this 避免回调函数中的 this 绑定 this 的方法 Function.prototype.call() Function.prototype.apply() Function.prototype.bind() 箭头函数中的 this this 关键字 涵义 t…...

数据库的备份和恢复

备份:完全备份,增量备份 完全备份:将整个数据库完整的进行备份 增量备份:在完全备份基础的之上,对后续新增的内容进行备份 备份的需求 1生产环境中,数据的安全性至关重要,任何数据都可能产生非…...

DS图—图非0面积/bfs【数据结构】

DS图—图非0面积 题目描述 编程计算由"1"围成的下列图形的面积。面积计算方法是统计"1"所围成的闭合曲线中"0"点的数目。如图所示,在10*10的二维数组中,"1"围住了15个点,因此面积为15。 提示&…...

Wnmp服务安装并结合内网穿透实现公网远程访问——“cpolar内网穿透”

文章目录 前言1.Wnmp下载安装2.Wnmp设置3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 WNMP是Windows系统下的绿色NginxMysqlPHP环境集成套件包,安装完成后即可得到一个Nginx MyS…...

2023版Pycharm关闭一直显示closing project,正在关闭项目

点击 帮助 下的 查找操作 英文版为 Help 下的 Find Action 输入 Registry 禁用 ide.await.scope.completion 即可 PS:按 Ctrl F 输入可以快速检索...

Gradle笔记 二 Gradle的基础Groovy

学习Groovy的必要性 首先Gradle是由Groovy写成的,而且构建脚本的语法都遵循Groovy的语法,所以要学好Gradle的前提是要基本了解Groovy的语法。 Groovy 简介 在某种程度上,Groovy可以被视为Java的一种脚本化改良版,Groovy也是运行在JVM上&am…...

浅谈剩余电流动作继电器在电动伸缩门的应用

摘 要:随着时代的发展,越来越多的小区、厂区、园区和学校等场所的大门安装了电动伸缩门,几乎可以说随处可见。电动伸缩门是一种长期在户外使用的设备,工作电压为220 V(过去也有380 V),其电机是处…...

stable diffusion安装踩坑之clip安装、git报错

clip本地安装环境链接问题 本节主要记录一下在windows安装stable diffusion时,clip脚本安装不上,本地安装时如何链接到当前库的问题 首先,在脚本安装clip不成功时,脚本会输出一个commend指令,复制到浏览器就可以很快…...

colmap gpu服务器安装

1.官方安装说明 https://colmap.github.io/install.html 后边有编译支持gpu的步骤!!! 2.sudo apt-get install libgtest-dev 3.cmakelists.txt 250行 set(CMAKE_CUDA_ARCHITECTURES “native”) 4. sudo apt-get install libqt5core5a sud…...

linux内的循环

格式 while 【 条件判断 】 do 语句体 done 上图 第一次代码,输入语句在外面,结果输入完(非hello)程序不断循环,没办法,ctrlc给程序终止了,然后把用户输入的语句放到了循环体里面…...

强化学习(RL)的学习笔记

1. 前言 (1)PPO的优点 PPO(Proximal Policy Optimization)算法相比其他强化学习方法有几个显著优点: 稳定性和鲁棒性:PPO通过限制策略更新的幅度来避免训练过程中的大幅波动,这增加了算法的稳…...

2023世界传感器大会开幕,汉威科技多领域创新产品引瞩目

11月5日,2023世界传感器大会在郑州国际会展中心正式拉开帷幕。据悉,本次大会由河南省人民政府、中国科学技术协会主办,郑州市人民政府、河南省工业和信息化厅、河南省科学技术协会、中国仪器仪表学会承办。 大会由“一会一赛一展”组成&#…...

什么是机器学习中的正则化?

1. 引言 在机器学习领域中,相关模型可能会在训练过程中变得过拟合和欠拟合。为了防止这种情况的发生,我们在机器学习中使用正则化操作来适当地让模型拟合在我们的测试集上。一般来说,正则化操作通过降低过拟合和欠拟合的可能性来帮助大家获得…...

PostgreSQL JDBC连接详解(附DEMO)

PostgreSQL JDBC连接详解 PostgreSQL JDBC连接详解摘要引言1. JDBC基础1.1 JDBC简介1.2 JDBC驱动程序1.3 建立JDBC连接 2. 配置PostgreSQL JDBC连接2.1 PostgreSQL连接JDBC2.2 PostgreSQL连接JDBC是否成功2.3 PostgreSQL连接JDBC获取表信息注释等2.4 PostgreSQL连接JDBC根据表名…...

学习视频剪辑:巧妙运用中画、底画,制作画中画,提升视频效果

随着数字媒体的普及,视频剪辑已经成为一项重要的技能。在视频剪辑过程中,制作画中画可以显著提升视频效果、信息传达和吸引力。本文讲解云炫AI智剪如何巧妙运用中画、底画批量制作画中画来提升视频剪辑水平,提高剪辑效率。 操作1、先执行云…...

Android Studio代码无法自动补全

Android Studio代码自动无法补全问题解决 在写layout布局文件时,代码不提示,不自动补全,可以采用如下方法: 点击File—>Project Structure,之后如图所示,找到左侧Modules,修改SDK版本号&…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes&#xff0…...

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

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

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)&#xff…...