Java设计模式之工厂模式 - 实践

news/2025/10/21 10:22:33/文章来源:https://www.cnblogs.com/wzzkaifa/p/19154323

需求说明

一个披萨订购的项目,要便于披萨种类的扩展,要便于维护

  1. 披萨的种类很多,比如GreekPizza、CheesePizza
  2. 披萨的制作有prepare、bake、cut、box
  3. 完成披萨店订购的功能

传统写法

Pizza.java

public abstract class Pizza {public abstract void prepare();private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void bake() {System.out.println(name + " baking");}public void cut() {System.out.println(name + " cutting");}public void box() {System.out.println(name + " boxing");}
}

奶酪披萨

public class CheesePizza extends Pizza {@Overridepublic void prepare() {System.out.println("给制作奶酪披萨准备原材料");}
}

希腊披萨

public class GreekPizza extends Pizza {@Overridepublic void prepare() {System.out.println("给制作希腊披萨准备原材料");}
}

披萨订购

public class OrderPizza {public OrderPizza() {Pizza pizza = null;String orderType;do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");} else {break;}pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza type:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

披萨店

public class PizzaStore {public static void main(String[] args) {new OrderPizza();}
}

这样就能根据输入的披萨种类,来制作对应的披萨
输出如下

input pizza type:
cheese
给制作奶酪披萨准备原材料
奶酪披萨 baking
奶酪披萨 cutting
奶酪披萨 boxing
input pizza type:
greek
给制作希腊披萨准备原材料
希腊披萨 baking
希腊披萨 cutting
希腊披萨 boxing
input pizza type:
hello
Process finished with exit code 0

这种写法的优点是比较好理解,简单易操作,但是缺点是违反了设计模式的ocp原则,即对扩展开发,对修改关闭。比如我们要增加一个新的Pizza种类,就需要修改OrderPizza中的代码,如果有好多个

简单工厂模式

针对上面写法的缺点进行改造,把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该类即可,其他有创建Pizza对象的代码就不需要修改了 -> 简单工程模式。
简单工厂模式属于创建型模式,是工厂模式的一种,由一个工厂对象决定创建出哪一种产品的实例。它定义了一个创建对象的类,由这个类封装实例化对象的行为。在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会用到工厂模式

工厂类

public class SimpleFactory {public Pizza createPizza(String type) {Pizza pizza = null;System.out.println("使用简单工厂模式");if (type.equals("greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (type.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");} else if (type.equals("pepper")){pizza = new PepperPizza();pizza.setName("胡椒披萨");} else {pizza = null;}return pizza;}
}

披萨订购类

public class OrderPizza {private SimpleFactory factory;private Pizza pizza;public OrderPizza(SimpleFactory factory) {this.factory = factory;String orderType = "";do {orderType = getType();pizza = this.factory.createPizza(orderType);if (pizza != null) {pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购披萨失败");break;}} while (true);}private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza type:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

披萨店

public class PizzaStore {public static void main(String[] args) {// 使用简单工厂模式new OrderPizza(new SimpleFactory());System.out.println("退出了程序");}
}

静态工厂模式

简单工厂模式也叫静态工厂模式,原因是创建对象的方法可以写成一个静态方法。将上面的代码做如下修改
SimpleFactory增加一个方法:

    public static Pizza createPizza2(String type) {Pizza pizza = null;System.out.println("使用静态工厂模式");if (type.equals("greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (type.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");} else if (type.equals("pepper")){pizza = new PepperPizza();pizza.setName("胡椒披萨");} else {pizza = null;}return pizza;}

OrderPizza2

public class OrderPizza2 {private Pizza pizza;public OrderPizza2() {String orderType = "";do {orderType = getType();// 直接使用类名调用pizza = SimpleFactory.createPizza2(orderType);if (pizza != null) {pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购披萨失败");break;}} while (true);}private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza type:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

披萨店

public class PizzaStore {public static void main(String[] args) {// 使用静态工厂模式new OrderPizza2();System.out.println("退出了程序");}
}

效果是一样的

工厂方法模式

假如有了新的需求:
客户在点披萨时,可以点不同的口味,比如北京的奶酪pizza、北京的胡椒pizza或者伦敦的奶酪pizza、伦敦的胡椒pizza
工厂方法模式就是定义一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类

北京奶酪披萨

public class BJCheesePizza extends Pizza {@Overridepublic void prepare() {setName("北京奶酪");System.out.println("为北京的奶酪披萨准备材料");}
}

北京胡椒披萨

public class BJPepperPizza extends Pizza {@Overridepublic void prepare() {setName("北京胡椒");System.out.println("为北京的胡椒披萨准备材料");}
}

伦敦奶酪披萨

public class LDCheesePizza extends Pizza {@Overridepublic void prepare() {setName("伦敦奶酪");System.out.println("为伦敦的奶酪披萨准备材料");}
}

伦敦胡椒披萨

public class LDPepperPizza extends Pizza {@Overridepublic void prepare() {setName("伦敦胡椒");System.out.println("为伦敦的胡椒披萨准备材料");}
}

OrderPizza

public abstract class OrderPizza {public abstract Pizza createPizza(String orderType);public OrderPizza() {Pizza pizza = null;String orderType = "";do {orderType = getType();pizza = createPizza(orderType);if (pizza != null) {pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购披萨失败");break;}} while (true);}private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza type:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

其中createPizza()这个抽象方法由子类去实现

北京OrderPizza

public class BJOrderPizza extends OrderPizza {@Overridepublic Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}return pizza;}
}

伦敦OrderPizza

public class LDOrderPizza extends OrderPizza {@Overridepublic Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}
}

PizzaStore

public class PizzaStore {public static void main(String[] args) {// 工厂方法模式:定一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类String location = "bj";if (location.equals("bj")) {// 创建北京口味的各种披萨new BJOrderPizza();System.out.println("退出了程序");} else if (location.equals("ld")) {// 创建伦敦口味的各种披萨new LDOrderPizza();System.out.println("退出了程序");}}
}

抽象工厂模式

抽象工厂模式将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类,程序员可以根据创建对象类型使用对象的工厂子类,这样将单个的简单工厂变成工厂簇,更利于代码的维护和扩展。

抽象工厂

public interface AbsFactory {Pizza createPizza(String orderType);
}

北京披萨工厂

public class BJFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("使用的是抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}return pizza;}
}

伦敦披萨工厂

public class LDFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("使用的是抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}
}

OrderPizza

public class OrderPizza {private AbsFactory factory;public OrderPizza(AbsFactory factory) {this.factory = factory;Pizza pizza = null;String orderType = "";do {orderType = getType();pizza = this.factory.createPizza(orderType);if (pizza != null) {pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购披萨失败");break;}} while (true);}private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza type:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

PizzaStore

public class PizzaStore {public static void main(String[] args) {// 抽象工厂模式:// 将工厂抽象成两层,抽象工厂和具体实现的工厂子类new OrderPizza(new BJFactory());}
}

小结

代码地址:
https://github.com/mundane799699/DesignPattern/tree/master/FactoryDesignPattern
参考:

尚硅谷Java设计模式(图解+框架源码剖析)



喜欢的朋友记得点赞、收藏、关注哦!!!

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

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

相关文章

【转】[C#] 要从接口取时间,单个订单查询和批量查询,写一个接口还是两个接口合适?

【转】[C#] 要从接口取时间,单个订单查询和批量查询,写一个接口还是两个接口合适?转自:豆包 建议分成两个独立接口,而非合并为一个。这种设计更符合接口的单一职责原则,能让接口语义更清晰、扩展性更强,同时避免…

2025 年药包材辅导公司最新推荐榜:GMP 验证 / 质量体系 / 实验室装修等服务优质机构权威评选

引言 药包材作为药品安全的 “第一道防线”,其质量直接关联用药安全与药品稳定性。随着《药品包装材料与药物相容性试验指导原则》等政策持续收紧,企业在 GMP 设备验证、洁净厂房设计、注册申报等环节面临严苛合规考…

2025年10月防脱生发产品推荐榜:十款临床验证口碑对比

脱发不再是“中年专属”,2025年国家卫健委发布的《中国脱发人群调查》显示,我国脱发人群已突破2.5亿,其中30岁以下占比高达60%。加班熬夜、高糖高油饮食、焦虑情绪让“发量焦虑”提前到来。很多人第一次走进皮肤科,…

2025 年国内优质不锈钢厂家最新推荐排行榜:含沈阳/东三省区域及水箱油罐等产品优质服务商楼梯/激光切割/桥梁杆/真空罐/扶手不锈钢厂家推荐

引言 当前国内不锈钢市场产品品类繁杂,从基础的板材、管材到定制化的水箱、油罐、桥梁杆等,覆盖建筑、化工、机械等多个领域,采购方常面临产品质量难甄别、供应商资质参差不齐的困境。部分供应商存在交货延迟、售后…

界面控件DevExpress WPF v25.2新功能预览 - 聚焦AI功能提升

界面控件DevExpress WPF v25.2新功能预览 - 聚焦AI功能提升DevExpress WPF 拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序…

CSS 预处理器:Sass的基本用法、核心特性 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 顶管源头厂家最新推荐榜单:F 型混凝土 / 水泥 / 电力 / 矩形 / 市政排水大口径优质供应商精选

引言 当前城市地下管网、综合管廊等基础设施建设进入高峰期,顶管作为核心建材的市场需求持续激增。但行业中仍存在产能不足导致供货滞后、工艺不规范引发质量隐患、新品牌实力难辨等问题,采购方常因信息不对称选错供…

使用DMA和PWM驱动16组WS2812 LED的STM32实现

STM32使用DMA和PWM来驱动16组WS2812 LED灯带。WS2812是一种智能控制LED,每个LED都需要24位数据(8位绿色,8位红色,8位蓝色),并且对时序要求非常严格。 硬件设计考虑GPIO选择:选择16个可用的GPIO引脚,最好是同一…

2025年GEO品牌推荐榜:云视GEO以全栈技术引领行业变革

文章摘要 本文基于2025年GEO行业趋势,深度分析用户对品牌推荐和排行的需求,重点推荐四川云视有客科技有限公司的云视GEO服务。通过解读其GEO-AI搜索优化技术、线性规划博弈算法及定制化方案,揭示如何实现干预延迟≤…

【开题答辩实录分享】以《 Python基于大数据的四川旅游景点数据分析与可视化》为例进行答辩实录分享 - 实践

【开题答辩实录分享】以《 Python基于大数据的四川旅游景点数据分析与可视化》为例进行答辩实录分享 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display…

linux 程序 启动命令

#!/bin/sh # 获取当前日期current_date=$(date +%Y-%m-%d) # 0. 关闭程序kill -9 `ps -ef|grep java | grep leaf-business-zyyk-flow | awk {print \$2}` > /dev/null 2>&1 # 删除创建日期在10天前的日志文…

2025 年台车炉厂家最新推荐榜,技术实力与市场口碑深度解析,助力企业精准选型天然气/燃气/热处理/全纤维/翻转式台车炉厂家推荐

引言 在工业制造领域,台车炉作为热处理关键设备,其性能直接关系到工件质量、生产效率与企业能耗成本。当前市场上,台车炉品牌数量繁杂,部分产品存在控温精度不足、能耗偏高、售后响应滞后等问题,叠加环保政策趋严…

2025 年贵阳家居品牌最新推荐榜,技术实力与市场口碑深度解析贵阳家居实木家具/贵阳家居布艺沙发/贵阳家居多功能沙发家居公司推荐

引言 伴随家居消费升级与行业智能化转型,贵阳家居市场呈现 “新旧品牌同台竞技” 的格局:既有深耕本地的老牌企业,也有凭借创新快速崛起的新锐力量。但市场繁荣背后,材质以次充好、环保不达标、售后缺位等问题仍困…

ida pro 9.2 接入 ida-pro-mcp

ida-pro-mcp 官方文档 https://github.com/mrexodia/ida-pro-mcp 已在是我的安装过过程 1. 安装IDA pro 9.2 ,默认路径 C:\Program Files\IDA Professional 9.2 2. 下载安装python及pip,下载python3.11压缩包到ida安…

2025 年最新高低温试验箱厂家排行榜:精选优质供应商,专业推荐助您精准选购合适设备恒温恒湿试验箱/高低温试验箱厂家推荐

引言 在工业生产与科研实验中,高低温试验箱是保障产品质量、推动科研进展的关键设备。但当前市场品牌繁杂,部分小型品牌缺乏核心技术,设备在温度控制精度、稳定性等方面难以达标,且行业标准执行不到位、售后服务不…

稀疏网格高斯-埃尔米特数值积分方法

稀疏网格方法是一种高效的高维数值积分技术,通过组合一维积分规则来避免"维度灾难"。MATLAB实现用于生成稀疏网格高斯-埃尔米特积分节点和权重。 function [nodes, weights] = sparseGridGH(d, level, vara…

2025 年淬火炉源头厂家最新推荐榜:聚焦技术创新与市场口碑深度解析,精选优质企业供采购参考

引言 随着工业制造向高精度、低能耗、智能化转型,淬火炉作为热处理环节的关键设备,其性能直接决定工件质量与生产效率。当前市场中,淬火炉厂家数量繁杂,部分企业存在技术滞后、产品适配性差、售后保障不足等问题,…

2025 年国际物流服务公司最新推荐排行榜:覆盖海运快递跨境专线,精选优质企业助力跨境电商商家高效选择合作伙伴

引言 在全球化贸易不断深入、跨境电商规模持续扩张的背景下,国际物流作为连接商家与全球市场的核心纽带,其服务质量直接影响商家的运营效率与市场竞争力。然而,当前市场上国际物流企业数量众多,服务水平参差不齐,…

跟着GPT5学习bert分类中[CLS]标记 hidden state的作用

gpt1 核心功能是什么 GPT-5 GPT‑1(Generative Pre-trained Transformer 1)是 OpenAI 于 2018 年 发布的第一个「生成式预训练 Transformer」模型。虽然与后来 GPT‑2、GPT‑3 甚至 GPT‑4 相比,它的规模很小(…

2025 年最新推荐立体画厂家权威榜单:涵盖 3D 光栅 / 装饰 / 三维等品类,助力精准选优质厂家

引言 当前立体画行业发展迅猛,市场上产品类型日益丰富,涵盖 3D 光栅立体画、立体光栅卡、3D 装饰立体画、三维立体画等多个品类,但同时也面临品牌杂乱、技术水平悬殊、产品质量参差不齐的问题。企业和消费者在选择时…