简单工厂模式详解

文章目录

  • 前言
  • 一、简单工厂模式定义
  • 二、举个例子
  • 三、简单工厂模式的缺点
  • 总结


前言

本篇我们了解一下简单工厂模式,它是设计模式的雏形,是学习设计模式的开端,我会结合案例说明它的设计思路。


一、简单工厂模式定义

简单工厂模式并不是GoF23个设计模式中的一员,但是一般将它作为学习设计模式的起点。简单工厂模式又称为静态方法模式(Static Factory Method Pattern),属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同的类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,这个类称为工厂类,被创建的实例通常都具有共同的父类。简单工厂模式的结构如下图:
在这里插入图片描述
在模式结构图中,Factory表示工厂类,它是整个模式的核心,负责实现创建所有实例的内部逻辑。工厂类可以被外部直接调用,创建所需的产品对象。工厂类中有一个负责生产对象的静态工厂方法,系统可以根据工厂方法所传入的参数,动态决定应该创建出哪一个产品类的实例。工厂方法是静态的,而且必须有返回类型,其返回类型为抽象产品类型,即Product类型;Product表示抽象产品角色,它是简单工厂模式所创建的所有对象的父类,负责定义所有实例所共有的公共接口;ConcreteProduct表示具体产品角色,它是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。一个系统中一般存在多个ConcreteProduct类,每种具体产品对应一个Concrete类。

二、举个例子

我们设计一个Coffee(咖啡类),它是一个抽象类,比如现在有两种具体咖啡,分别是AmericanCoffee(美式咖啡)和LatteeCoffee(拿铁咖啡),因此我们需要一个具体工厂去创建具体咖啡产品,我们再定义一个生产咖啡的工厂SimpleCoffeeFactory,它们的模式结构图如下:
在这里插入图片描述
AmericanCoffee和LatteeCoffee需要继承Coffee这个抽象产品,同时都要实现Coffee中的抽象方法,比如获取咖啡名称,添加牛奶,加糖等方法,而SimpleCoffeeFactory是生产咖啡的工厂,需要提供一个静态的创建咖啡的方法,同时这个方法的返回值类型必须是Coffee抽象类,这就体现了多态的特性,即父类引用可以指向子类对象。
相关代码如下:
抽象咖啡类,其实也可以是接口,我定义的是抽象类:

abstract public class Coffee {abstract protected void getName();abstract protected void addMilk();abstract protected void addSugar();
}

美式咖啡(具体产品):

public class AmericanCoffee extends Coffee{@Overrideprotected void getName() {System.out.println("American Coffee...");}@Overrideprotected void addMilk() {System.out.println("add American coffee milk...");}@Overrideprotected void addSugar() {System.out.println("add American coffee sugar...");}
}

拿铁咖啡(具体产品):

public class LatteCoffee extends Coffee{@Overrideprotected void getName() {System.out.println("Latte Coffee...");}@Overrideprotected void addMilk() {System.out.println("add Latte Coffee milk...");}@Overrideprotected void addSugar() {System.out.println("add Latte Coffee sugar...");}
}

咖啡工厂类:

public class SimpleCoffeeFactory {public static Coffee createFactory(String type){Coffee coffee = null;if ("AmericanCoffee".equals(type)){coffee = new AmericanCoffee();} else if ("LatteeCoffee".equals(type)) {coffee = new LatteCoffee();}return coffee;}
}

在咖啡工厂类中定义了一个创建咖啡的静态方法,入参是咖啡的类型,根据类型判断返回具体咖啡对象。
在外部可以创建一个咖啡店类,调用工厂提供的静态方法去创建具体的咖啡:

public class CoffeeStory {public static void main(String[] args) {orderCoffee("AmericanCoffee");}public static Coffee orderCoffee(String name){SimpleCoffeeFactory simpleCoffeeFactory = new SimpleCoffeeFactory();Coffee coffee = simpleCoffeeFactory.createFactory(name);coffee.getName();coffee.addMilk();coffee.addSugar();return coffee;}
}

三、简单工厂模式的缺点

在简单工厂模式中,工厂类包含必要的判断逻辑,决定在什么时候创建哪一个产品类的实例,客户端可以直接免除直接创建产品对象的责任,而仅仅“消费”产品,简单工厂模式通过这种方式实现了对责任的划分。但是由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响;同时系统扩展较为困难,一旦添加新产品就不得不修改工厂逻辑,违反了开闭原则。比如上面的案例,如果我们再增加一种意大利咖啡,那么在创建具体产品类的同时,静态工厂方法的代码逻辑需要改动。因此,简单工厂模式是存在很多问题的,通常并不用于实际开发中。


总结

本篇我们结合实际案例说明了简单工厂模式的设计原理,和它包含的角色,下面我们继续看另一种设计更合理的工厂方法模式。

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

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

相关文章

看一眼Mysql查询语句

目录 🛻 查询数据 🛻基本查询语句 🛻单表查询 🚕查询所有字段 🚕查询指定字段 🚕查询指定记录 🚕带in关键字的查询 🚕带between and的范围查询 🚕带like的字符匹…

10个在线ai文案自动生成器,轻松写出高质量原创文案

在数字营销时代,撰写引人注目的标题和吸引人的营销文案至关重要。然而,写作优质文案需要耗费时间和精力。幸运的是,现在有许多在线AI文案自动生成器可以帮助我们快速创作出高质量的标题和营销文案。本文将介绍十款值得推荐的在线AI文案自动生…

微信小程序事件点击跳转页面的五种方法

第一种:标签 这是最常见的一种跳转方式,相当于html里的a标签 <navigator url"/pages/main/main"></navigator>第二种:wx.navigateTo({})方法 1.前端wxml <button bindtap"getCeshi" type"primary"> 测试按钮 </button>…

flink水位线传播及任务事件时间

背景 本文来讲解一下flink的水位线传播及对其对任务事件时间的影响 水位线 首先flink是通过从源头生成水位线记录的方式来实现水位线传播的&#xff0c;也就是说水位线是嵌入在正常的记录流中的特殊记录&#xff0c;携带者水位线的时间戳&#xff0c;以下我们就通过图片的方…

springCloud通过两种方式配置热更新

该热更新实际就是通过改动nacos官网里面的配置管理的妹纸内容实现 定义一个config包&#xff0c;在该包下面复制该代码 package cn.itcast.user.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.spring…

【C++】多线程编程二(std::thread详解)

目录 std::thread详解 &#xff08;1&#xff09;启动线程 ①无参无返回的函数作为入参 ②函数对象&#xff08;仿函数&#xff09;作为入参 &#xff08;2&#xff09;不等待线程detch() &#xff08;3&#xff09;等待线程完成join() &#xff08;4&#xff09;向线程…

力扣142. 环形链表 II

题目 给定一个链表的头节点head&#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回null。 链接&#xff1a;142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 题解 方法一&#xff1a;设置两个指针&#xff0c;一个指针指向链表头结点&#…

云原生之深入解析Flink on k8s的运行模式与实战操作

一、概述 Flink 核心是一个流式的数据流执行引擎&#xff0c;并且能够基于同一个 Flink 运行时&#xff0c;提供支持流处理和批处理两种类型应用。其针对数据流的分布式计算提供了数据分布&#xff0c;数据通信及容错机制等功能。Flink 官网不同版本的文档flink on k8s 官方文…

CVE-2023-1454注入分析复现

简介 JeecgBoot的代码生成器是一种可以帮助开发者快速构建企业级应用的工具&#xff0c;它可以通过一键生成前后端代码&#xff0c;无需写任何代码&#xff0c;让开发者更多关注业务逻辑。 影响版本 Jeecg-Boot<3.5.1 环境搭建 idea 后端源码&#xff1a; https://git…

vue3项目创建(vite3+ts+elementui-plus)

文章目录 1.创建工程 1.创建工程 目的&#xff1a;vue3vitets 安装依赖&#xff0c;安装vite的工具 Vite下一代的前端工具链为开发提供极速响应v4.3 npm install -g create-vite创建工程 create-vite font-userui --template vue-ts –template vue-ts 后面的是配置模板&#…

git bash设置字体大小

背景 git bash默认字体太小了&#xff0c;每次读信息都要伸头盯着屏幕&#xff0c;很不自在&#xff0c;不符合我的风格&#xff0c;so let’s do it&#xff01; 修改前的git bash&#xff1a; 正确的打开方式 1、在任意目录下&#xff0c;右键选择“Git Bash Here”&…

ubuntu netplan工具原理(网络配置、ip修改ip、固定ip)(NetworkManager)

https://netplan.io/ 文章目录 netplan工作原理netplan -h原翻译命令释义- help&#xff1a;显示netplan的帮助消息。- apply&#xff1a;将当前netplan配置应用到运行系统。示例命令&#xff1a;netplan apply --debug- generate&#xff1a;从/etc/netplan/*.yaml生成特定于后…

JVM 运行流程、类加载、垃圾回收

一、JVM 简介 1、JVM JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java 虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机&#xff1a;JVM、VMwave、Virtual Box。 JVM 和其他两个虚拟机的区别…

Android Java代码与JNI交互字符串转换(四)

🔥 Android Studio 版本 🔥 🔥 创建JNIString.java 🔥 package com.cmake.ndk1.jni;public class JNIString {static{System.loadLibrary("string-lib");}public native String callNativeString(String str);public native void stringMethod(String str)…

C/C++的发展历程和未来趋势

文章目录 C/C的起源C/C的应用C/C开发的工具C/C未来趋势 C/C的起源 C语言 C语言是一种通用的高级编程语言&#xff0c;由美国计算机科学家Dennis Ritchie在20世纪70年代初期开发出来。起初&#xff0c;C语言是作为操作系统UNIX的开发语言而创建的。C语言的设计目标是提供一种功…

【玩转循环】探索Python中的无限可能性

前言 循环可能是每个编程语言中使用比较多的语法了&#xff0c;如果能合理利用好循环&#xff0c;就会出现意想不到的结果&#xff0c;大大地减少代码量&#xff0c;让机器做那些简单枯燥的循环过程&#xff0c;今天我将为大家分享 python 中的循环语法使用。&#x1f697;&am…

spring复习:(22)实现了BeanNameAware等Aware接口的bean,相应的回调方法是在哪里被调用的?

AbstractAutowireCapableBeanFactory的doCreateBean用来创建bean, 其中调用了initializeBean方法对bean进行初始化 initializeBean包含如下代码&#xff1a; 而invokeAwareMethods代码如下&#xff1a; 可见其分别判断是否实现了BeanNameAware接口、BeanClassLoaderAware接口…

基于ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升技术

空间数据获取与制图 1.1 软件安装与应用讲解 1.2 空间数据介绍 1.3海量空间数据下载 1.4 ArcGIS软件快速入门 1.5 Geodatabase地理数据库 ArcGIS专题地图制作 2.1专题地图制作规范 2.2 空间数据的准备与处理 2.3 空间数据可视化&#xff1a;地图符号与注记 2.4 研究区…

Maven下载和配置教程:Windows、Mac和Linux系统安装指南

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Nginx配置白名单访问

一、背景 在项目运行的时候&#xff0c;需要设置特定的访问权限&#xff0c;以拒绝其他可能存在的恶意访问。 二、配置 2.1、关键字 允许访问关键字&#xff1a;allow 屏蔽访问关键字&#xff1a;deny 2.2、作用域 作用域如下&#xff1a; http&#xff1a;所有网站屏蔽I…