Java设计模式 | 简单工厂模式

在这里插入图片描述

概述

需求

设计一个咖啡店点餐系统
设计一个咖啡类(Coffee);并定义其两个子类(美式咖啡AmericanCoffee和拿铁咖啡LatteCoffee);再设计一个咖啡店类(CoffeeStore),其具备点咖啡的功能。

类图

image.png

咖啡类
public abstract class Coffee {// 获取咖啡名public abstract String getName();// 加糖public void addSugar(){System.out.println("加糖");}// 加奶public void addMilk(){System.out.println("加奶");}
}

美式咖啡类
public class AmericanCoffee extends Coffee {@Overridepublic String getName() {return "美式咖啡";}
}

拿铁咖啡类
public class LatteCoffee extends Coffee {@Overridepublic String getName() {return "拿铁咖啡";}
}

咖啡店类
public class CoffeeStore {public Coffee orderCoffee(String type) {// 根据类型创建咖啡实例Coffee coffee = null;if("Latte".equals(type)) {coffee = new LatteCoffee();}else if("Americano".equals(type)) {coffee = new AmericanCoffee();}else {System.out.println("Sorry, we don't have this kind of coffee.");}// 加糖和奶coffee.addSugar();coffee.addMilk();return coffee;}
}
测试
public class Client {public static void main(String[] args) {// 1 创建咖啡店类CoffeeStore coffeeStore = new CoffeeStore();// 2 点咖啡Coffee coffee = coffeeStore.orderCoffee("Latte");System.out.println(coffee.getName());}
}

在Java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new,就会对该对象耦合严重,假如需要更换对象,所有new的地方都需要修改一遍,这显然违背了开闭原则。如果使用工厂来生产对象,就只需要和工厂打交道就好了,彻底和对象解耦,如果需要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的。所以说,工厂模式的最大优点就是:解耦

三种工厂:

  • 简单工厂模式(不属于GOF的23种经典设计模式)
  • 工厂方法模式
  • 抽象工厂模式

简单工厂模式

简单工厂不是一种设计模式,反而比较像是一种编程习惯。

结构

简单工厂包含以下角色:

  • 抽象产品:定义了产品的规范,描述了产品的主要特征和功能(通用行为)
  • 具体产品:实现或继承抽象产品(接口/抽象类)的子类
  • 具体工厂:提供了创建产品的方法,调用者通过该方法来获取产品(根据传递的不同参数来创建不同的产品示例)
实现

image.png
咖啡类:

public abstract class Coffee {// 获取咖啡名public abstract String getName();// 加糖public void addSugar(){System.out.println("加糖");}// 加奶public void addMilk(){System.out.println("加奶");}
}

美式咖啡类:

public class AmericanCoffee extends Coffee {@Overridepublic String getName() {return "美式咖啡";}
}

拿铁咖啡类:

public class LatteCoffee extends Coffee {@Overridepublic String getName() {return "拿铁咖啡";}
}

简单咖啡工厂类:

public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {// 根据类型创建咖啡实例Coffee coffee = null;if("Latte".equals(type)) {coffee = new LatteCoffee();}else if("Americano".equals(type)) {coffee = new AmericanCoffee();}else {System.out.println("Sorry, we don't have this kind of coffee.");}return coffee;}
}

咖啡店类:

public class CoffeeStore {public Coffee orderCoffee(String type) {// 实例化工厂SimpleCoffeeFactory simpleCoffeeFactory = new SimpleCoffeeFactory();// 调用生产咖啡的方法Coffee coffee = simpleCoffeeFactory.createCoffee(type);// 加糖和奶coffee.addSugar();coffee.addMilk();return coffee;}
}

测试:

public class Cilent {public static void main(String[] args) {// 创建咖啡店类对象CoffeeStore coffeeStore = new CoffeeStore();// 点咖啡Coffee coffee = coffeeStore.orderCoffee("Latte");System.out.println(coffee.getName());}
}

总结

工厂(factory)处理创建对象的细节,一旦有了SimpleCoffeeFactory,CoffeeStore类中的orderCoffee()就变成此对象的客户,后期如果需要Coffee对象直接从工厂中获取即可。这样就解除了CoffeeStore和Coffee实现类的耦合,同时又产生了新的耦合,CoffeeStore和SimpleCoffeeFactory的耦合,工厂对象和商品对象的耦合。
后期如果需要增加新咖啡,势必需要修改SimpleCoffeeFactory的代码,违反了开闭原则。工厂的客户端可能有很多,如创建美团外卖等,这样只需要修改工厂类的代码,省去了其他的操作。

简单工厂简化了客户端操作,客户端可以调用工厂方法来获取具体的产品,而无需直接与具体产品类交互,降低了耦合,但是有一个很大的问题就是不够灵活,如果需要添加新产品,就需要修改工厂类的代码。

优点:

  • 封装了创建对象的过程,可以通过参数直接获取对象
  • 把对象的创建和业务逻辑层分开,避免了修改客户端的代码,如果要实现新产品直接修改工厂类,不需要在原代码中修改,降低客户代码修改的可能性,更容易扩展

缺点:

  • 增加新产品时需要修改工厂类的代码,违背了开闭原则

扩展(静态工厂)

在实际开发中,一部分开发人员将工厂类中创建对象的功能定义成静态的,这就是静态工厂模式,也不属于23种设计模式,是一种编程习惯。
好处就是客户端可以不用实例化工厂对象,直接调用即可。

public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {// 根据类型创建咖啡实例Coffee coffee = null;if("Latte".equals(type)) {coffee = new LatteCoffee();}else if("Americano".equals(type)) {coffee = new AmericanCoffee();}else {System.out.println("Sorry, we don't have this kind of coffee.");}return coffee;}
}

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

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

相关文章

一文搞定JVM相关的命令汇总,推荐收藏!

一、简介 虽然目前市场上有很多成熟的 JVM 可视化监控分析工具,但是所有的工具其实都依赖于 JDK 的接口和底层相关的命令,了解这些命令的使用对于我们在紧急情况下排查 JVM 相关的线上故障,会有更加直观的帮助。 下面我们一起来看看 JVM 常…

云服务器2核4g能支持多少人同时访问?腾讯云和阿里云PK

腾讯云轻量应用服务器2核4G5M配置性能测评,腾讯云轻量2核4G5M带宽服务器支持多少人在线访问?并发数10,支持每天5000IP人数访问,腾讯云百科txybk.com整理2核4G服务器支持多少人同时在线?并发数测试、CPU性能、内存性能、…

智慧安全:守护智慧城市的安全屏障

随着信息技术的迅猛发展,智慧城市已成为现代城市发展的重要方向。智慧城市通过集成应用先进的信息通信技术,实现城市管理、服务、运行的智能化,为城市的可持续发展注入了新的活力。然而,在智慧城市的建设过程中,安全问…

综合系列之大四学生如何摆脱焦虑,找回自己?

注意: 焦虑是一种常见的情绪,它通常表现为紧张、不安、恐惧和担忧等情绪。当焦虑情绪影响到日常生活和工作时,就需要采取适当的措施来应对。 一、焦虑原因 1. 就业压力:随着毕业的临近,可能会感到就业压力增大&#xf…

Java IO模型

NIO Java IO 模型1. 什么是IO计算机结构角度应用程序角度 2. 常见的内存模型3. Java中常见的IO模型3.1 BIO(Blocking I/O)3.2 NIO(Non-blocking/New I/O)同步非阻塞 IO 模型I/O 多路复用模型 3.3 AIO(Asynchronous I/O…

C++:类的6大默认成员函数(拷贝构造函数篇)

文章目录 1、拷贝构造函数的概念const用途 2、拷贝构造函数的特性浅拷贝/值拷贝 前言:Hello,大家好,咱这篇博客继续默认成员函数,今天的笔记分享为拷贝构造函数~ 1、拷贝构造函数的概念 在创建对象时,我们能否创建一个与已存在对象一某一样的…

2024.3.9|第十五届蓝桥杯模拟赛(第三期)

2024.3.9|十五届蓝桥杯模拟赛(第三期) 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第九题 第十题 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C学习笔记,常言道,不积跬步无以至千里&…

Spring项目-前端问题:Can‘t find variable:$

在写Spring项目代码时,后端调试没问题,部署程序到Safari上出现Cant find variable:$ 问题 部署到Chrome上出现Uncaught ReferenceError: $ is not defined问题 检查前端代码后发现是JS代码里,函数与jQuery前后位置有问题 改换位置后页面可正常…

MySQL 数据库设计范式

第一范式(1NF) 每一列都是不可分割的原子数据项第二范式(2NF) 在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖) 1.函数依赖A->B,如果通过A属性(属性组)的值…

彻底学会系列:一、机器学习之梯度下降(2)

1 梯度具体是怎么下降的? ∂ J ( θ ) ∂ θ \frac{\partial J (\theta )}{\partial \theta} ∂θ∂J(θ)​(损失函数:用来衡量模型预测值与真实值之间差异的函数) 对损失函数求导,与学习率相乘,按梯度反方…

耳机壳UV树脂制作私模定制耳塞需要什么样的设备和技术?

制作私模定制耳塞需要使用到一些特定的设备和技术,包括但不限于以下内容: 耳模制作工具:用于获取用户耳型的耳模制作工具,如硅胶、橡皮泥等。需要使用熟练的手法和技术,确保耳模的准确性和稳定性。UV树脂:…

牛客题霸-SQL进阶篇(刷题记录二)

本文基于前段时间学习总结的 MySQL 相关的查询语法,在牛客网找了相应的 MySQL 题目进行练习,以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多,因此本文不再展示,只提供 MySQL 代码与示例输出。 部分题目因…

在openSUSE-Leap-15.5-DVD-x86_64中使用微信wechat-beta-1.0.0.238

在openSUSE-Leap-15.5-DVD-x86_64中使用微信wechat-beta-1.0.0.238 参考文章: 《重磅!微信(Universal)UOS版迎来全新升级丨统信应用商店上新 》统信软件 2024-03-13 17:45 北京 https://mp.weixin.qq.com/s/VSxGSAPTMPH4OGvGSilW…

计算机毕业设计-基于python的旅游信息爬取以及数据分析

概要 随着计算机网络技术的发展,近年来,新的编程语言层出不穷,python语言就是近些年来最为火爆的一门语言,python语言,相对于其他高级语言而言,python有着更加便捷实用的模块以及库,具有语法简单…

JAVA EE (计算机是如何工作的)

学前注意事项 出去面试的时候java岗位不需要懂前端(会少量讲解) 但是我们做项目的时候多少回用到一些前端的东西 1.什么是计算机 1.1前情提要 不仅仅只有电脑是计算机 计算机还不仅仅是电脑手机和平板 路由器 智能洗衣机 刷脸打卡机都可以说是计算…

智慧交通:构建智慧城市的重要一环

随着信息技术的飞速发展,智慧城市已成为现代城市发展的重要方向。作为智慧城市的重要组成部分,智慧交通以其高效、便捷、环保的特性,成为推动城市现代化进程的关键力量。本文将从智慧交通的概念、发展现状、面临挑战以及未来趋势等方面&#…

C#,图论与图算法,有向图(Graph)之环(Cycle)判断的颜色算法与源代码

1 检查该图是否包含循环 给定一个有向图,检查该图是否包含循环。如果给定的图形至少包含一个循环,则函数应返回true,否则返回false。 方法:深度优先遍历可用于检测图中的循环。连接图的DFS生成树。只有当图中存在后缘时,图中才存在循环。后边是从节点到自身(自循环)或…

Huggingface 笔记:大模型(Gemma2B,Gemma 7B)部署+基本使用

1 部署 1.1 申请权限 在huggingface的gemma界面,点击“term”以申请gemma访问权限 https://huggingface.co/google/gemma-7b 然后接受条款 1.2 添加hugging对应的token 如果直接用gemma提供的代码,会出现如下问题: from transformers i…

Docker 从0安装 nacos集群

前提条件 Docker支持一下的CentOs版本 Centos7(64-bit),系统内核版本为 3.10 以上Centos6.5(64-bit) 或者更高版本,系统内核版本为 2.6.32-431 或者更高版本 安装步骤 使用 yum 安装(CentOS 7下) 通过 uname -r 命令查看你当…

室友打团太吵?一条命令断掉它的WiFi

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:更多干货,请关注专栏《网络安全自学教程》 ARP欺骗原理 1、arpspoof实现ARP欺骗1.1、主机探测1.2、欺骗…