【设计模式】工厂方法模式Factory(Java)

news2024/11/23 12:15:18

文章目录

  • 1. 定义
  • 2. 类图
  • 3. Java实现案例
    • 3.1 抽象类:Pizza和PizzaStore
    • 3.2 具体披萨:北京两种上海两种共四种
    • 3.3 具体披萨店:北京店和上海店
    • 3.4 测试主方法

1. 定义

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类

2. 类图

在这里插入图片描述

  • 所以具体产品必须实现一个共同的Product接口(抽象类)
  • Creator是一个抽象类,它实现了所有到操作产品的方法,但不实现工厂方法factoryMethod
  • ConcreteCreator负责创建一个或多个具体Product
  • 工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中

这里遵循依赖倒置的原则要依赖抽象,不要依赖具体类

注意⚠️:在设计模式中,“实现一个接口”不一定就是指“写一个类,并利用implement关键词来实现某个java接口”,“实现一个接口”泛指实现某个超类型(类或者接口)的某个方法

3. Java实现案例

场景:

  • 披萨店生产披萨
  • 披萨有相同的处理流程,但有不同的处理方法,比如披萨都需要烘烤,但不同的披萨也许有不同的烘烤温度要求
  • 不同的披萨店能制作的披萨类型也不同
  • 易于扩展,增加新类型的披萨或新的披萨店

思考准备:

  • 根据工厂方法的类图,Product即为披萨、Creator即为披萨店,因此设计抽象Class:披萨、披萨店
  • 根据“工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中”,我们需要在抽象Creator中设计抽象创建披萨店方法,并由继承它的子类进行具体实现
  • 易于扩展,具体披萨类继承抽象披萨类、具体披萨店类继承抽象披萨店类。

在这里插入图片描述

3.1 抽象类:Pizza和PizzaStore

Pizza:

package Factory;

import java.util.ArrayList;

/**
 * 抽象披萨
 */
public abstract class Pizza {

    String name; // 名称
    String dough; // 面团类型
    String sauce; // 酱料类型
    ArrayList toppings = new ArrayList(); // 一套装饰品佐料

    // 准备
    void prepare(){
        System.out.println("Preparing " + name);

        System.out.println("Tossing dough..");

        System.out.println("Adding sauce..");

        System.out.println("Adding toppings:");
        for(int i = 0; i < toppings.size(); i++){
            System.out.println("  " + toppings.get(i));
        }
    }

    // 烘焙
    void bake(){
        System.out.println("Bake for 30 min at 360");
    }
    // 分切
    void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }
    // 打包
    void box(){
        System.out.println("Place pizza in official PizzaStore box");
    }

    public String getName(){
        return name;
    }



}

PizzaStore:

package Factory;

/**
 * 抽象披萨商店
 */
public abstract class PizzaStore {
    public Pizza orderPizza(String type){
        Pizza pizza;
        // 创建披萨
        pizza = createPizza(type);
        // 制作披萨并打包
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        // 返回披萨
        return pizza;
    }

    protected abstract Pizza createPizza(String type);
}

3.2 具体披萨:北京两种上海两种共四种

北京披萨1

package Factory;

/**
 * 具体披萨
 */
public class BjStyleCheesePizza extends Pizza {
    public BjStyleCheesePizza(){
        name = "BeiJing Cheese Pizza";
        dough = "Thin Curst Dough";
        sauce = "LaoGanMa Sauce";

        toppings.add("Grated Reggiano Cheese");
    }
}

北京披萨2

package Factory;

/**
 * 具体披萨
 */
public class BjStyleVeggiePizza extends Pizza {


    public BjStyleVeggiePizza(){
        name = "BeiJing Veggie Pizza";
        dough = "Bj2 Dough";
        sauce = "Bj2 Sauce";

        toppings.add("Bj2 Cheese");
    }

    // 这个北京披萨覆盖了cut方法,将披萨切成正方形
    @Override
    void cut() {
        System.out.println("Cutting the pizza into square slices");
    }
}

上海披萨1

package Factory;

/**
 * 具体披萨
 */
public class ShStyleCheesePizza extends Pizza {
    public ShStyleCheesePizza(){
        name = "Shanghai Veggie Pizza";
        dough = "Sh2 Dough";
        sauce = "Sh2 Sauce";

        toppings.add("Sh2 Cheese");
    }
}

上海披萨2

package Factory;

/**
 * 具体披萨
 */
public class ShStyleVeggiePizza extends Pizza {
    public ShStyleVeggiePizza(){
        name = "Shanghai Veggie Pizza";
        dough = "Sh2 Dough";
        sauce = "Sh2 Sauce";

        toppings.add("Sh2 Cheese");
    }
}

3.3 具体披萨店:北京店和上海店

工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中。在本Demo中“创建对象的行为”即具体类中的createPizza方法。

北京店能生产北京的两种披萨

package Factory;

/**
 * 具体披萨商店
 */
public class BeiJingPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new BjStyleCheesePizza();
        } else if (type.equals("veggie")) {
            return new BjStyleVeggiePizza();
        }
        // 等等其他类型的上海披萨

        return null;
    }
}

同理,上海店能生产上海店两种披萨

package Factory;

/**
 * 具体披萨商店
 */
public class ShangHaiPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new ShStyleCheesePizza();
        } else if (type.equals("veggie")) {
            return new ShStyleVeggiePizza();
        }
        // 等等其他类型的上海披萨

        return null;
    }
}

3.4 测试主方法

package Factory;

/**
 * 测试主方法
 */
public class MainPizzaTest {
    public static void main(String[] args) {


        PizzaStore pizzaStore1 = new BeiJingPizzaStore(); // 北京披萨店
        Pizza cheeseFormBj = pizzaStore1.orderPizza("cheese"); // 点一份cheese
        System.out.println(cheeseFormBj.getName());


        // 其他同上,如预定上海披萨店的Veggie披萨

    }
}

输出:
在这里插入图片描述

代码结构:
在这里插入图片描述

参考文献:《Head First设计模式(中文版)》弗里曼

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

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

相关文章

基于JAVA的XX公司固定资产管理系统的设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 本课题研究对象是中小企业财务管理系统&#xff0c;设计采用自己开发实践和所学知 识&#xff0c;系统部分主要分为以下…

汽车主机厂Adams/Car悬架动力学开发最全攻略

​​​​​​​一、写在前面 实际经历告诉我们&#xff0c;当我们接触一个新事物或学习一项新的技能时&#xff0c;入门往往是最为困难的&#xff0c;迷茫、彷徨、无助…… 正是基于同样的经历&#xff0c;在掌握Adams/Car软件的应用后&#xff0c;作者即开始构思如何将自己的…

论文投稿指南——中文核心期刊推荐(电工技术)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

linux后台自定义后台服务service(已filebeat举例)

文章目录一、配置攥写1&#xff09;安装filebeat和配置相关修改2&#xff09;常用命令二、启动顺序1&#xff09;命令循序2&#xff09;systemctl添加自定义系统服务&#xff08;服务填写指南&#xff09;3&#xff09;linux的systemctl命令详解及使用教程三、遇到的坑点和报错…

One-Hot 独热编码

1. 什么是独热编码 独热编码&#xff0c;又称一位有效编码。采用N位状态寄存器来对N个状态进行编码&#xff0c;直观来说就是有多少个状态就有多少比特&#xff0c;除了有效的比特为1外&#xff0c;其他都为0. 2. 独热编码过程 &#xff08;1&#xff09;将分类值映射到整数…

Simulcast与SVN

什么是Simulcast: 一个客户端向服务器发送高清&#xff0c;标清&#xff0c;低清三种视频流&#xff0c;服务器根据其他接收客户端的带宽情况分发不同的视频流。Simulcast不仅有客户端的工作&#xff0c;还有服务器的工作。 开启Simulcast的三种方式: Munging SDP方式 添加assr…

网络实验①——同Vlan下相互通信

实验要求&#xff1a; pc0与pc1互通pc2与pc3互通实验步骤&#xff1a; A交换机配置&#xff1a; enable config t hostname switch-A vlan 10 vlan 20 exit interface f0/1 switch access vlan 10 no shutdown interface f0/2 switch access vlan 20 no shutdown interface f0/…

无线耳机哪个品牌好一点?真无线蓝牙耳机推荐品牌

蓝牙耳机随着近几年的快速发展&#xff0c;已经成为了人们外出时必不可少的数码产品之一。而现如今&#xff0c;市面上的蓝牙耳机品牌众多&#xff0c;挑选起来让人眼花缭乱&#xff0c;人们在选择时不免陷入纠结。那么&#xff0c;无线耳机哪个品牌好一点&#xff1f;下面&…

day23【代码随想录】翻转二叉树、对称二叉树、相同的树、另一棵树的子树、完全二叉树的结点个数

文章目录前言一、翻转二叉树&#xff08;力扣226&#xff09;1、递归法1、使用前序遍历2、使用后序遍历2、迭代法1、层序遍历二、对称二叉树&#xff08;力扣101&#xff09;三、相同的树&#xff08;力扣100&#xff09;四、另一棵树的子树&#xff08;力扣572&#xff09;五、…

[附源码]Nodejs计算机毕业设计教师信息采集系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

docker容器中DPDK对网卡SR-IOV支持实验

主要是验证下容器运行DPDK&#xff0c;如何对SR-IOV进行支持 1 VF创建方法 在未开启SR-IOV时&#xff0c;通过DPDK提供的./dpdk-devbind.py脚本可知&#xff0c;当前系统一共有一块82599网卡&#xff0c;拥有2个网口&#xff0c;PCI的地址是18:00.0和18:00.1,如下图所示 启用…

华为配置动态路由ISIS协议

华为配置动态路由ISIS协议一、路由基础知识二、路由器配置接口IP地址&#xff08;一&#xff09;配置R1、R2、R3网络&#xff08;二&#xff09;配置R1、R2、R3环回网络接口&#xff08;三&#xff09;测试直连网络三、启动进程号&#xff0c;配置实体名称&#xff08;一&#…

JVM之堆

堆的基本内容&#xff1a; Java堆&#xff08;Java Heap&#xff09;是虚拟机所管理的内存中最大的一块&#xff0c;Java堆是被所有线程共享的一块内存区域&#xff0c;在虚拟机启动时创建&#xff0c;此内存区域的唯一目的就是存放对象实例&#xff0c;Java 世界里“几乎”所…

【每日挠头算法题】Leetcode 989. 数组形式的整数加法 —— 高精度加法解法

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;每日挠头算法题 文章目录一、题目描述二、思路及代码实现今天为大家带来的是力扣上的一道简单题&#xff1…

Spring的秒表StopWatch优雅的程序计时器 -第455篇

历史文章&#xff08;文章累计450&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 走进MyBatis源码一探Spring扩展点「知识…

排水监测传感器数据采集传感节点接入网关产品介绍

一、产品概述 传感节点接入网关是一款工业级网关&#xff0c;可将Modbus RTU协议的设备数据转换为MQTT协议格式再远传至数据中心&#xff0c;支持采集数字量输入信号&#xff0c;支持输出数字量控制信号。 传感节点接入网关具备一体化采集、传输、控制功能&#xff0c;集成了…

IDEA自定义JavaDOC注释模板

文章目录IDEA自定义JavaDOC注释模板方法注释模板1、创建模板2、设置模板内容-JavaDoc格式3、Define4、Edit VariablesIDEA自定义JavaDOC注释模板 JavaDOC注释模板共分为两种&#xff1a; 类注释模板方法注释模板 方法注释模板 1、创建模板 File–>Settings–>Editor…

FixMatch: Simplifying Semi-Supervised Learning with Consistency and Confidence

FixMatch: Simplifying Semi-Supervised Learning with Consistency and Confidence, NIPS, 2020 要点&#xff1a; 1、首先&#xff0c;基于 “弱增强的未标记样本的模型预测” 生成伪标签&#xff1b;接着&#xff0c;对于给定的样本&#xff0c;只有模型预测的置信度高时&a…

详细复习云开发~小程序【云存储、云函数】

文章目录一&#xff0c;云开发~云存储1-1&#xff0c;云开发控制台管理文件1-2&#xff0c;上传图片到云存储1-3&#xff0c;给商品列表加商品图片1-4&#xff0c;上传视频到云存储1-5&#xff0c;上传word&#xff0c;excel文件到云存储1-5-1&#xff0c;上传之前先选择文件1-…

mybatis if test对Intger判空的坑、原理及解决方法

文章目录问题描述源码分析解决方法问题描述 Mybatis在进行<if test"status! null and status! ">非空判断操作时&#xff0c;如果status为0的时候&#xff0c;该判断条件的值为false 写法如下&#xff1a; <select id"countByBySearchCondition&quo…