java设计模式-工厂方法模式

1.工厂方法(FactoryMethod)模式的定义

定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。

2.工厂方法模式的主要优缺点

优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点:

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

3.工厂方法模式主要角色

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

4.工厂方法模式结构图

在这里插入图片描述

5.工厂方法模式的实现

5.1 普通工厂模式,以消息发送为例

  • 创建消息发送接口
package com.lw.designpattern.factorymethod.normal;/*** @Classname Sender* @Description 消息发送接口* @Author lw* @Date 2019-12-21 15:24*/
public interface Sender {public void send();
}
  • 创建邮件发送类,实现Sender接口
package com.lw.designpattern.factorymethod.normal;/*** @Classname MailSender* @Description 邮件发送* @Author lw* @Date 2019-12-21 15:25*/
public class MailSender implements Sender {@Overridepublic void send() {System.out.println("邮件发送。。。。。。");}
}
  • 创建短信发送类,实现Sender接口
package com.lw.designpattern.factorymethod.normal;/*** @Classname SmsSender* @Description 短信发送* @Author lw* @Date 2019-12-21 15:26*/
public class SmsSender implements Sender {@Overridepublic void send() {System.out.println("短信发送。。。。。。");}
}

如果后续有其他方式消息发送,则只需要创建消息发送类,实现Sender接口即可。违背开闭原则

  • 测试代码
 /*** 工厂设计模式-普通工厂模式*/@Testpublic void testNormalFactory(){// 邮件发送Sender sender = new MailSender();sender.send();// 短信发送Sender sender1 = new SmsSender();sender1.send();}
  • 打印结果
    在这里插入图片描述

5.2 工厂方法模式,以饮料产品及生产为例

  • 创建饮料产品接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname DrinksProduct* @Description 饮料产品接口* @Author lw* @Date 2019-12-21 14:22*/
public interface DrinksProduct {public void show();
}
  • 创建可乐产品类,实现DrinksProduct接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname ColaProduct* @Description 可乐产品* @Author lw* @Date 2019-12-21 14:30*/
public class ColaProduct implements DrinksProduct {@Overridepublic void show() {System.out.println("可乐产品显示。。。。。。");}
}
  • 创建雪碧产品类,实现DrinksProduct接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname SpriteProduct* @Description 雪碧产品* @Author lw* @Date 2019-12-21 14:31*/
public class SpriteProduct implements DrinksProduct {@Overridepublic void show() {System.out.println("雪碧产品显示。。。。。。");}
}
  • 创建饮料工厂接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname DrinksFactory* @Description 饮料工厂接口* @Author lw* @Date 2019-12-21 15:04*/
public interface DrinksFactory {public DrinksProduct product();
}
  • 创建可乐工厂类,实现DrinksFactory接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname ColaFactory* @Description 可乐工厂* @Author lw* @Date 2019-12-21 15:05*/
public class ColaFactory implements DrinksFactory {@Overridepublic DrinksProduct product() {System.out.println("开始生产可乐。。。。。。");return new ColaProduct();}
}
  • 创建雪碧工厂类,实现DrinksFactory接口
package com.lw.designpattern.factorymethod.multi;/*** @Classname SpriteFactory* @Description 雪碧工厂* @Author lw* @Date 2019-12-21 15:05*/
public class SpriteFactory implements DrinksFactory {@Overridepublic DrinksProduct product() {System.out.println("开始生产雪碧。。。。。。");return new SpriteProduct();}
}

后续增加其他产品,则需要增加一个具体产品类和一个对应的具体工厂类即可。满足开闭原则。

  • 测试代码
/*** 工厂设计模式-工厂方法模式*/@Testpublic void testFactoryMethod(){// 生产可乐DrinksFactory drinksFactory = new ColaFactory();DrinksProduct drinksProduct = drinksFactory.product();drinksProduct.show();// 生产雪碧DrinksFactory drinksFactory1 = new SpriteFactory();DrinksProduct drinksProduct1 = drinksFactory1.product();drinksProduct1.show();}

打印结果
在这里插入图片描述

6.工厂方法模式的应用场景

  • 客户只知道创建产品的工厂名,而不知道具体的产品名。
  • 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  • 客户不关心创建产品的细节,只关心产品的品牌。

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

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

相关文章

HPM6750系列--第九篇 GPIO详解(基本操作)

一、目的 在之前的博文中我们主要介绍了不同系统不同开发编译调试环境的配置和操作(命令行方式、Visual Studio Code、Segger Embedded Studio for RISC-V),以帮助大家准备好学习环境为目的,但是未涉及到芯片本身以及外设的讲解。…

【linux】图形界面Debian的root用户登陆

图形界面Debian默认不允许以root用户登录。这是出于安全考虑,以防止用户使用root权限执行可能损害系统的操作。 如果需要使用root用户,可以通过以下步骤进行登录: 打开终端,使用su命令切换到root用户。修改/etc/gdm3/daemon.con…

大型网站架构演进过程

架构演进 大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以P计的数据和面对数以亿计的用户,问题就会变得很棘手。大型网站架构主要就是解决这类问题。 架构选型是根据当前业务需要来的&…

时序预测 | Python实现XGBoost电力需求预测

时序预测 | Python实现XGBoost电力需求预测 目录 时序预测 | Python实现XGBoost电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行业预测进行比较…

JS中的String常用的实例方法

splice():分隔符 把字符串以分隔符的形式拆分为数组 const str pink,red;const arr str.split(,);console.log(arr);//Array[0,"pink";1:"red"]const str1 2022-4-8;const arr1 str1.split(-);console.log(arr1);//Array[0,"2022";1:"…

Vue3快速上手笔记

Vue3快速上手 1.Vue3简介 2020年9月18日,Vue.js发布3.0版本,代号:One Piece(海贼王)耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址:https://github.com/vuejs/vue-next/release…

实操Nginx(七层代理)+Tomcat多实例部署,实现负载均衡和动静分离

目录 Tomcat多实例部署(192.168.17.27) 1.安装jdk,设置jdk的环境变量 2.安装tomcat在一台已经部署了tomcat的机器上复制tomcat的配置文件取名tomcat1 ​编辑 编辑配置文件更改端口号,将端口号改为8081 启动 tomcat&#xff…

SpringBoot之响应的详细解析

2. 响应 前面我们学习过HTTL协议的交互方式:请求响应模式(有请求就有响应) 那么Controller程序呢,除了接收请求外,还可以进行响应。 2.1 ResponseBody 在我们前面所编写的controller方法中,都已经设置了…

Linux面试题精选:提升你的面试准备

大家有关于JavaScript知识点不知道可以去 🎉博客主页:阿猫的故乡 🎉系列专栏:JavaScript专题栏 🎉ajax专栏:ajax知识点 🎉欢迎关注:👍点赞🙌收藏✍️留言 学习…

CD8+T细胞通过NKG2D-NKG2DL轴维持对MHC-I阴性肿瘤细胞的杀伤

今天给同学们分享一篇实验文章“CD8 T cells maintain killing of MHC-I-negative tumor cells through the NKG2D-NKG2DL axis”,这篇文章发表在Nat Cancer期刊上,影响因子为22.7。 结果解读: MHC-I阴性肿瘤的免疫疗法需要CD8 T细胞 作者先…

下午好~ 我的论文【yolo1~4】(第二期)

写在前面:本来是一期的,我看了太多内容了,于是分成三期发吧 TAT (捂脸) 文章目录 YOLO系列v1v2v3v4 YOLO系列 v1 You Only Look Once: Unified, Real-Time Object Detection 2015 ieee computer society 12.3 CCF-C…

高云GW1NSR-4C开发板M3核串口通信

1.PLLVR频率计算 高云的M3核要用到PLLVR核,其输出频率FCLKIN*(FBDIV_SEL1)/(IDIV_SEL1),但同时要满足FCLKIN*(FBDIV_SEL1)*ODIV_SEL)/(IDIV_SEL1)的值在600MHz和1200MHz之间。例如官方示例,其输入频率FCLKIN50MHz,要输出80MHz&am…

appium2.0.1安装完整教程+uiautomator2安装教程

第一步:根据官网命令安装appium(Install Appium - Appium Documentation) 注意npm前提是设置淘宝镜像: npm config set registry https://registry.npmmirror.com/ 会魔法的除外。。。 npm i --locationglobal appium或者 npm…

oracle DG 三种应用机制

首先理解不管是哪种机制,oracle都不是从主库直接传归档文件到备库,而是通过网络将主库的redo数据传输到备库: 1、普通DG是主库发生日志切换,备库把接收到的redo数据在备库通过归档进程生成为归档文件进行应用 2、ADG则是备库把接收…

Java技术栈 —— 微服务框架Spring Cloud —— Ruoyi-Cloud 学习(二)

RuoYi项目开发过程 一、登录功能(鉴权模块)1.1 后端部分1.1.1 什么是JWT?1.1.2 什么是Base64?为什么需要它?1.1.3 SpringBoot注解解析1.1.4 依赖注入和控制反转1.1.5 什么是Restful?1.1.6 Log4j 2、Logpack、SLF4j日志框架1.1.7 如何将项目打包成指定bytecode字节…

基于springboot的教学在线作业管理系统(源码+调试)

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题,今天给大家介绍…

性能提升100%、存储节约50%!猕猴桃游戏搭载OceanBase开启云端手游新篇章

近日,武汉灵动在线科技有限公司(以下简称“灵动在线”)与 OceanBase 达成合作,旗下品牌猕猴桃游戏的“游戏用户中心(微信小程序)”和“BI 分析报表业务系统“两大关键业务系统全面接入 OB Cloud 云数据库&a…

windows下redis 设置开机自启动

1,在redis的目录下执行(执行后就作为windows服务了) redis-server --service-install redis.windows.conf 2,安装好后需要手动启动redis redis-server --service-start 3,停止服务 redis-server --service-stop

用标记接口定义类型

标记接口是不含有任何方法的接口,它的目的是通过将特定接口应用于类来为该类添加类型信息。以下是一个示例: public interface Drawable {// 标记接口,不包含任何方法 }public class Circle implements Drawable {private int radius;public…

【C++11特性篇】利用 { } 初始化(1)

前言 大家好吖,欢迎来到 YY 滴C系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! 目录 一.回顾C98标准中{}的使用二.一切皆可用…