【工厂方法模式-3】工厂方法模式的代码实现及使用场景

news2024/10/7 14:26:33

 在前面我们学习了简单工厂模式,简单工厂模式适用于产品对象比较固定的使用场景。简单工厂模式工厂模式存在两个比较大的问题,一个是新产品的加入必须修改工厂类,违反了开闭原则;另一个是所有产品对象都与工厂类耦合,无法对工厂类进行抽象,不利于系统扩展。

 工厂方法模式就可以很好的解决这两个问题,不再使用单一的工厂类创建所有产品,而是针对不同产品使用不同工厂创建,提供一个与产品等级结构相对应的工厂等级结构。

1. 定义

工厂方法模式定义一个用于创建对象的工厂接口,让子类决定创建哪种类型的产品对象,使得具体产品对象的创建延迟到抽象工厂的子类中进行。工厂方法模式又称工厂模式,是一种创建型模式。

 在工厂方法模式中,存在4个角色:

  • 抽象产品角色:它定义了产品接口,是工厂生产具体产品的父类,可以是接口或抽象类。
  • 具体产品角色:它实现了抽象产品接口,是工厂类生产的具体产品对象。
  • 抽象工厂角色:抽象工厂接口声明了工厂方法,用于返回产品,是工厂方法模式的核心,所有的具体工厂都要实现抽象工厂接口。
  • 具体工厂角色:它是抽象工厂类的子类,实现了抽象工厂生命的工厂方法,返回一个具体的产品实例对象,和具体产品角色一一对应。

 可以看出来,工厂方法模式和简单工厂模式唯一的区别就是多了抽象工厂角色,它的出现就很好的解决了简单工厂模式的两个缺点。


2. 代码实现

 现在通过这样一个需求,有一个电子工厂,可以生产不同的电子产品,分别是电脑和手机。

  • 抽象产品角色
// 1.抽象的产品角色
public abstract class Product {
    // 业务方法 - 开机
    protected abstract void powerOn();

}
  • 具体产品角色
// 2.具体的产品角色 - 电脑
class Computer extends Product {
    @Override
    protected void powerOn() {
        System.out.println("电脑开机!");
    }
}

// 2.具体的产品角色 - 手机
class Phone extends Product {
    @Override
    protected void powerOn() {
        System.out.println("手机开机!");
    }
}
  • 抽象工厂角色
// 3.抽象的工厂角色
public interface Factory {
    Product createProduct();
}
  • 具体工厂角色
// 4.具体的工厂角色 - 电脑工厂
class ComputerFactory implements Factory {
    @Override
    public Product createProduct() {
        return new Computer();
    }
}

// 4.具体的工厂角色 - 电脑工厂
class PhoneFactory implements Factory {
    @Override
    public Product createProduct() {
        return new Phone();
    }
}
  • 客户端
public class Client {
    public static void main(String[] args) {
        // 电脑产品
        Factory computerFactory = new ComputerFactory();
        Product computer = computerFactory.createProduct();
        computer.powerOn();
        // 手机产品
        PhoneFactory phoneFactory = new PhoneFactory();
        Product phone = phoneFactory.createProduct();
        phone.powerOn();
    }
}

3. UML类图

 这里忽略客户端client:
在这里插入图片描述


4. 总结

4.1 优点

  • 和其他工厂模式一样,将对象的创建和使用过程分离,做进一步的解耦,用户只需关注所使用的工厂即可;
  • 工厂和产品都有同层级抽象设计,这也是工厂方法模式被称为多态工厂的原因,所以扩展性更强;
  • 在新加入具体产品时,只需增加对应的具体工厂和具体产品角色即可,无需修改源代码,符合开闭原则;

4.2 缺点

  • 具体产品角色都要有与之对应的具体工厂,增加了类的个数,增加了系统复杂性,造成系统额外的运行开销;
  • 工厂和产品均使用抽象层开发,无形中增加了代码理解的难度。

4.3 适用场景

  • 客户端不知道要具体要创建的产品对象,而只关注产品的工厂;
  • 对一些无法获取到源代码的场景下,工厂或者产品的接口只有字节码;
  • 对象的创建过程比较复杂,可能涉及到一些io操作或者数据库连接等;

5. 问题

  • 工厂方法模式中的工厂方法可否是静态方法?

  不可以,因为静态方法是属于类的,只能通过类名.方法名来创建对象,这样抽象工厂角色就没有存在的意义,无法在工厂的维度上做抽象的扩展。

  • 抽象工厂和具体工厂没有存在的意义,开发的时候直接面向抽象产品角色编程也可以

  其实工厂存在的意义是使得工厂创建和使用过程分离,做进一步的解耦,这是创建型设计模式的核心所在,工厂用来做生产,客户端去调用做业务逻辑;

  另外还可以考虑一种场景,如果产品对象的创建过程比较复杂,可能涉及到一些jdbc连接、io操作等,举个例子,有个开发场景要记录业务日志,有产品角色需要写入到数据库,有产品角色需要记录到本地磁盘文件中。对于这样的场景,我们可以把比较复杂的jdbc连接,io操作的初始化写入到工厂类中执行,客户端就不用关心这些复杂的操作,只需要使用创建好的对象就可以。

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

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

相关文章

校友录网站

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字):网站前台: 关于我们、联系我们、资讯信息、用户信息、用户动态、动态评论 管理员功能: 1、管理关…

基于vmdk文件创建虚拟机

基于vmdk文件创建虚拟机 1、准备vmdk文件 下载地址如下: 链接:https://pan.baidu.com/s/1coQuZw8cgg5oU5bSegsS7Q?pwd=5mv0 提取码:5mv0 账号/密码:root/sinzuo 2、创建虚拟机 选择自定义的方式创建虚拟机 硬件兼容性选择17,尽可能的向下兼容。 选择稍后安装操作系…

使用 IQR、Z-score、LOF 和 DBSCAN 进行异常值检测

你在处理异常值吗?哪种方法更适合检测偏斜或正态分布数据的异常值? 无论你是在执行 EDA 之前进行数据清理过程,将数据传递给机器学习模型,还是执行任何统计测试,本文都将帮助你获得许多此类问题的答案以及实际应用。 …

Static、#define、const、mutable、typedef

Static、#define、const、mutable、typedef 代码存储区域:常量区、代码区、静态区(全局区)、堆区、栈区 栈区向下增长,堆区向上增长。栈由系统管理,没有内存碎片,每个元素之间都是连续的,大小…

MAXENT模型的生物多样性生境模拟与保护优先区甄选、自然保护区布局优化评估及论文写作技巧

【查看原文】基于MAXENT模型的生物多样性生境模拟与保护优先区甄选、自然保护区布局优化评估及论文写作技巧 随着生物多样性全球大会的举办,不论是管理机构及科研单位、高校都在积极准备,根据国家林草局最新工作指示,我国将积极整合、优化自…

【Django项目开发】功能菜单模型类设计、视图类设计要点(一)

一、抽象模型类设计 1、抽象模型类设计的作用: 1、定义所有模型类的公共属性,当其他的模型类继承该抽象模型类时,就具备了模型类中的属性了;在项目开发中,减少代码的编写 2、抽象模型类中经常定义的字段包括&#xff…

HFSS使用经验二

目录 一、绘制空气盒 二、Driven Solution Setup 的设置 ​三、如何添加圆场放大图 四、仿真之前的Validate 五、开始仿真 六、仿真过程Solution Data的查看 一、绘制空气盒 选择Padding type为Absolute Offset 设定Boundary为Radiation辐射边界 空气盒比较大&#xff…

数据校验-springboot

前置知识 先了解一下JSR、Hibernate Validator、Spring Validation: JSR(Java Specification Request)规范是Java EE 6中的一项子规范,也叫作Bean Validation。它指定了一整套基于bean的验证API,通过标注给对象属性添…

数据可视化之中国足球队在国际足联及亚洲的历史排名看这儿

最近最热的体育盛事莫过于世界杯了,四年一届的足球盛事,正在卡塔尔激战正酣。这时候可能会有球迷疑问:怎么没看到中国队呢?也有网友调侃说中国队被分到工程队去了。 泱泱大国,难道中国十几亿人口,一个足球队…

【Javassist】快速入门系列02 使用Javassist实现方法执行时间统计

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 前言 上一章我们介绍了使用Javassist实现一个简单的Hello World程序,学会了Javassist创建类和新增方法。本章主要介绍如何使用Javassist实现一个无侵入的方法执行时间统计 …

DCN神州数码——DHCP相关操作指令(超详细)

DHCP服务器配置 service dhcp 启动DHCP 服务器或中继功能 ip dhcp pool pool1 network-address 1.1.1.1 24 default-router dns-server 8.8.8.8 domain-name dcn.com netbios-name-server 2.2.2.2 lease 5 ip dhcp excluded-address 2.2.2.2 创建DHCP地址池pool1配置地…

PHP反序列化详解(一)——反序列化基础

今天继续给大家介绍渗透测试相关知识,本文主要内容是PHP反序列化详解(一)——反序列化基础。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负&#x…

西藏旅行网站

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字): (1)旅游线路信息发布以及预定功能:顾客可通网站查看相应的旅游线路信息 和预定旅游线路功能,管理…

OpenCV(8)-OpenCV中的形态学

OpenCV中的形态学 形态学概述 什么是形态学处理: 基于图像形态进行处理的一些基本方法 这些处理方法基本上是对二进制图像进行处理卷积核决定这图像处理后的效果基本方法: 腐蚀与膨胀开运算闭运算顶帽黑帽 图像二值化 将图像的每个像素变成两种值&a…

服务器设置tomcat开机自启动(cmd命令行语句)

1 找到tomcat安装目录,进入bin/文件夹下面,在此打开windows 命令行窗口。 2 输入 service install tomcatXXX将tomcat注册成为windows服务,其中tomcatXXX为服务名。 3查看刚刚注册的服务 “我的电脑”-》右键管理 发现刚刚的服务是手动的&…

DevOps-6:Jenkins使用技巧

1、如何提升Jenkins的Job并行构建数 默认情况下,Jenkins只配置了2个Executor,即只允许最多2个Job同时构建,这个值可以修改: 在Manage Jenkins>Configure System里,找到 # of executors,修改这个值就好&…

DW学生美食网页设计作业——餐饮美食汉堡企业网站6页面带轮播(HTML+CSS+JavaScript)

👨‍🎓静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计👩‍🎓,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等,用的最多的还是DW,当然不同软件写出的…

cython混淆加密

python代码是一种解释型的语言,有了代码和环境就可以执行,它无需编译。如果需要对代码进行混淆,可以借助cython这个库。它的安装很简单,直接运行pip install cython就可以安装。 进行代码混淆之前,还需要一个环境&…

windows下编译libevent源码

《Linux下编译libevent源码》讲述了linux下编译libevent源码的方法,本文讲述其在windows平台的编译。 一、下载libevent源码 https://libevent.org/ 下载libevent源码并解压。 二.安装依赖项 下载安装OpenSSL。https://slproweb.com/products/Win32OpenSSL.html 三…

MySQL8.0高级篇(下)-事务与日志和备份

文章目录一、事务基础知识1、数据库事务概述1.1 基本概念1.2 事物的ACID特性1.3 事务的状态2、如何使用事务2.1 显式事务2.2 隐式事务2.3 隐式提交数据的情况2.4 使用举例3、事务隔离级别3.1 数据准备3.2 数据并发问题3.3 SQL中的四种隔离级别3.4 MySQL支持的四种隔离级别4、事…