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

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

需求说明

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

  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.jsqmd.com/news/18204/

相关文章:

  • 【转】[C#] 要从接口取时间,单个订单查询和批量查询,写一个接口还是两个接口合适?
  • 2025 年药包材辅导公司最新推荐榜:GMP 验证 / 质量体系 / 实验室装修等服务优质机构权威评选
  • 2025年10月防脱生发产品推荐榜:十款临床验证口碑对比
  • 2025 年国内优质不锈钢厂家最新推荐排行榜:含沈阳/东三省区域及水箱油罐等产品优质服务商楼梯/激光切割/桥梁杆/真空罐/扶手不锈钢厂家推荐
  • 界面控件DevExpress WPF v25.2新功能预览 - 聚焦AI功能提升
  • CSS 预处理器:Sass的基本用法、核心特性 - 详解
  • 2025 顶管源头厂家最新推荐榜单:F 型混凝土 / 水泥 / 电力 / 矩形 / 市政排水大口径优质供应商精选
  • 使用DMA和PWM驱动16组WS2812 LED的STM32实现
  • 2025年GEO品牌推荐榜:云视GEO以全栈技术引领行业变革
  • 【开题答辩实录分享】以《 Python基于大数据的四川旅游景点数据分析与可视化》为例进行答辩实录分享 - 实践
  • linux 程序 启动命令
  • 2025 年台车炉厂家最新推荐榜,技术实力与市场口碑深度解析,助力企业精准选型天然气/燃气/热处理/全纤维/翻转式台车炉厂家推荐
  • ida pro 9.2 接入 ida-pro-mcp
  • 2025 年最新高低温试验箱厂家排行榜:精选优质供应商,专业推荐助您精准选购合适设备恒温恒湿试验箱/高低温试验箱厂家推荐
  • 2025 年淬火炉源头厂家最新推荐榜:聚焦技术创新与市场口碑深度解析,精选优质企业供采购参考
  • 2025 年国际物流服务公司最新推荐排行榜:覆盖海运快递跨境专线,精选优质企业助力跨境电商商家高效选择合作伙伴
  • 跟着GPT5学习bert分类中[CLS]标记 hidden state的作用
  • 2025 年最新推荐立体画厂家权威榜单:涵盖 3D 光栅 / 装饰 / 三维等品类,助力精准选优质厂家
  • WSL1升级为WSL2
  • 详细介绍:关于容器Docker
  • 完整教程:计算机视觉进阶教学之Mediapipe库(一)
  • 实用指南:【办公类-116-01】20250929家长会PPT(Python快速批量制作16:9PPT相册,带文件名,照片横版和竖版)
  • 为什么String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上?公共池和堆又是什么?
  • Docker 部署微服务项目保姆级教程
  • 审视生产制造ERP,发掘零售高效协同路径
  • 2025年发电机厂家推荐排行榜,发电机组,柴油发电机组,康明斯发电机,玉柴发电机,高压发电机,大功率发电机公司推荐
  • 2025年信息流代运营服务商权威推荐榜:专业投放策略与高转化效果深度解析
  • 2025年法兰保护罩厂家权威推荐榜:阀门保温罩/法兰罩/法兰防溅罩/法兰保护套,专业防护与耐用品质深度解析
  • 生物信息 R语言和 cytoscape 相互沟通的组件RCy3,构建cytoscape网络表 节点类型表 链接边的表,并推送到cytoscape - 详解
  • 2025 年大路灯品牌最新推荐榜,技术实力与市场口碑深度解析,精选优质源头厂家