2_工厂设计_工厂方法和抽象工厂

news2024/7/6 18:21:14

工厂设计模式-工厂方法

1.概念

工厂方法模式(Fatory Method Pattern ) 是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类工厂方法让类的实例化推迟到子类中进行。

在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节。

2.案例说明和分析

2.1 定义一个创建对象的接口

public interface ICourse {
    void record(); //录制抽象功能
}
public class JavaCourse implements ICourse {
    public void record() {
        System.out.println("录制Java课程");
    }
}
public class PythonCourse implements ICourse {
    public void record() {
        System.out.println("录制Python课程");
    }
}

/** 工厂模型 */
public interface ICourseFactory {
    ICourse create();
}

2.2 定义接口和实现类

public class JavaCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new JavaCourse();
    }
}
public class PythonCourseFactory implements ICourseFactory {
    public ICourse create() {
        return new PythonCourse();
    }
}

2.3实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

public class FactoryMethodTest {
    public static void main(String[] args) {
        ICourseFactory factory = new PythonCourseFactory();
        ICourse course = factory.create();
        course.record();
        factory = new JavaCourseFactory();
        course = factory.create();
        course.record();
    }
}

2.4 类图

在这里插入图片描述

3.总结

使用步骤:

创建一个接口A(实现抽象接口功能名write() )和实现类AImpl(实现逻辑代码:writ(){…})。

在创建创建一个接口工厂B(实现抽象功能返回接口A对象: creatA();)和实现类BImpl(实现逻辑返回AImpl实现类对象:createA(){ return new AImpl();})。

创建一个调用类 -> B b = new BImpl(); A a = b.createA(); a.write();

代码实现:

public interface A {
    void write(); 
}
//业务实现逻辑
public class AImpl implements A {
    public void write() {
        //不依赖于产品类实例如何被创建、实现等细节 
        System.out.println("写Java作业");
    }
}

//-------------------------------
public interface B {
     A createA();
}
public class BImpl implements B {
    public A createA() {
        //创建对象需要大量重复的代码
        return new AImpl(); //一个类通过其子类来指定创建哪个对象;
    }
}

B b = new BImpl();
A a = b.createA();
a.write();

为什么要使用工厂方法了啊?解决什么问题。

  1. 创建对象需要大量重复的代码;
  2. 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节 ;
  3. 一个类通过其子类来指定创建哪个对象;

工厂方法也有缺点

  1. 类的个数容易过多,增加复杂度
  2. 增加了系统的抽象性和理解难度

工厂设计模式-抽象工厂

1.案例说明和分析

//步骤1:创建接口和实现类
public interface ICourse {
    /* 录制视频 */
    void record();
}
public class JavaCourse implements ICourse {
    public void record() {
        System.out.println("录制Java课程");
    }
}
//多个....


// 步骤2: 创建抽象工厂类,并创建抽象方法返回实现类对象(接口对象)
public abstract class CourseFactory {
    public void init(){
        System.out.println("初始化基础数据");
    }
    protected abstract ICourse createCourse();
    
    //(都属于同一组的产品(小米空调,小米电视,小米手机)之间有一些联系) 多个....
}



//步骤3:继承抽象类工厂并实现抽象方法(创建实现类并返回)
public class JavaCourseFactory extends CourseFactory {
    public ICourse createCourse() {
        super.init();
        return new JavaCourse();
    }
}
//多个....


// 步骤4:创建继承抽象类的实例对象,并调用实现类中的业务逻辑方法
public class AbstractFactoryTest {
    public static void main(String[] args) {
        //一起使用创建对象需要大量重复的代码,这里就解决了。
        CourseFactory factory = new JavaCourseFactory();
        factory.createCourse().record();
        //多个...
    }
}

2.类图

在这里插入图片描述

3.总结

3.1 创建步骤:

  • 步骤1:创建接口和实现类
  • 步骤2: 创建抽象工厂类,并创建抽象方法返回实现类对象(接口对象)
  • 步骤3:继承抽象类工厂并实现抽象方法(创建实现类并返回)
  • 步骤4:创建继承抽象类的实例对象,并调用实现类中的业务逻辑方法

3.2 使用理解

强调的是系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

同一产品结构下还有格力热水器,格力空调,格力洗衣机。

在这里插入图片描述

在这里插入图片描述

3.3使用场景

如需要创建小米品牌一组家电(电视,空调,电饭锅等等)的对象,一个一个创建代码过多而且创建过程过程复杂,这时可以用抽象工厂方法封装一起来,调用就会变得简单。

如果创建多种品牌家电,每种品牌等级和价格不同,这时候就使用抽象工厂方法封装,传入什么参数调用什么等级家电产品,返回一组家电对象

参考:
https://refactoringguru.cn/design-patterns/factory-method
https://www.yuque.com/huangjinshidai-1wt9t/ocmvo8/zr4ypvhosvzzmh24?singleDoc#

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

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

相关文章

阿里开源AnyText:可在图像中生成任意精准文本,支持中文!

‍随着Midjourney、Stable Difusion等产品的出现,文生图像领域获得了巨大突破。但是想在图像中生成/嵌入精准的文本却比较困难。 经常会出现模糊、莫名其妙或错误的文本,尤其是对中文支持非常差,例如,生成一张印有“2024龙年吉祥…

数据分析基础之《pandas(1)—pandas介绍》

一、pandas介绍 1、2008年Wes McKinney(韦斯麦金尼)开发出的库 2、专门用于数据分析的开源python库 3、以numpy为基础,借力numpy模块在计算方面性能高的优势 4、基于matplotlib能够简便的画图 5、独特的数据结构 6、也是三个单词组合而…

2024年数学建模美赛能用chatGPT之类的AI吗?官方给了明确规定!

这两年chatGPT等大语言模型火了,能对话,自然也能回答数学建模方面的问题。 那美赛能不能用这些AI呢?2024年美赛官方对chatGPT等的使用做出了明确的规定(其中的VI. Contest Instructions部分): https://ww…

《2024 AIGC 应用层十大趋势白皮书》:近屿智能OJAC带您一起探索AI未来

Look!👀我们的大模型商业化落地产品📖更多AI资讯请👉🏾关注Free三天集训营助教在线为您火热答疑👩🏼‍🏫 近日国际知名咨询机构IDC发布《2024 AIGC 应用层十大趋势白皮书》的发布&am…

水文模型(科普类)

SWMM 模型概况: SWMM5 系列拥有编辑区域数据的功能,而且能模拟水文、 水力和水质。其核心部分是管道汇流计算模块,提供了恒定流法、运动波法和动力波法三种水动力学 方法。其中动力波法通过求解完整的圣维南方 程组进行计算,能够…

WPF自定义漂亮顶部工具栏 WPF自定义精致最大化关闭工具栏 wpf导航栏自定义 WPF快速开发工具栏

在WPF应用程序开发中,自定义一个漂亮的顶部工具栏具有多重关键作用,它不仅增强了用户体验,还提升了整体应用的专业性和易用性。以下是对这一功能的详细介绍: 首先,自定义顶部工具栏是用户界面设计的重要组成部分&…

508基于51单片机的火灾检测与报警系统设计

基于51单片机的火灾检测与报警系统设计[proteus仿真] 火灾检测与报警系统这个题目算是课程设计和毕业设计中常见的题目了,本期是一个基于51单片机的火灾检测与报警系统设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】,赞赏任意文章 …

BigDecimal的性能问题

BigDecimal 是 Java 中用于精确计算的数字类,它可以处理任意精度的小数运算。由于其精确性和灵活性,BigDecimal 在某些场景下可能会带来性能问题。 BigDecimal的性能问题 BigDecimal的性能问题主要源于以下几点: 内存占用:BigDec…

华为OD机试 - 反射计数(Java JS Python C)

题目描述 给定一个包含 0 和 1 的二维矩阵。 给定一个初始位置和速度,一个物体从给定的初始位置出发,在给定的速度下进行移动,遇到矩阵的边缘则发生镜面发射。 无论物体经过 0 还是 1,都不影响其速度。 请计算并给出经过 t 时间单位后,物体经过 1 点的次数。 矩阵以左…

国产编程语言炫彩,界面库ui dll,有人了解吗

中文编程: 中英文双语编程, 中英一键切换, 中英对照, 中文为主, UNICODE/ANSI编码都支持; 完全免费: 炫语言免费, 调试器免费, IDE绿色版无需安装; 纯文本: 纯文本格式代码, 随意复制粘贴, GIT代码托管, 多人合作开发; PY风格: PY风格代码, 通过代码缩进确定作用域 非 大花括…

B+树索引及其原理

MySQL索引的底层结构是B树,为什么它会选择这个结构?联合索引是怎么实现的?最左侧匹配原则的原理是什么?本文将一一解答这些疑惑。 1 前置知识 在学习B树之前,我们先了解下其他的树形结构:二叉树、平衡二叉…

C++中的返回值优化(RVO)

一、命名返回值优化(NRVO) 是Visual C2005及之后版本支持的优化。 具体来说,就是一个函数的返回值如果是一个对象。那么,正常的返回语句的执行过程是,把这个对象从当前函数的局部作用域,或者叫当前函数的…

vue+element弹窗内---下拉框定位问题解决(方法之一)

问题: 加了 :popper-append-to-body"false" 这个属性也不好用时 可以试试这个 解决: 第一步: 找到el-select标签添加(popper-class"popperClass")属性-----如下图 第二步:在css中添加如下代码即可 ::v-deep .popperClass{ top:auto !important; }

Java学习苦旅(二十二)——MapSet

本篇博客将详细讲解Map和Set。 文章目录 搜索概念模型 MapMap.Entry<K, V>Map的常用方法说明TreeMap和HashMap的区别 Set常用方法说明TreeSet和HashSet的区别 结尾 搜索 概念 Map和set是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例…

【win11 绕过TPM CPU硬件限制安装】

Qt编程指南 VX&#xff1a;hao541022348 ■ 下载iso文件■ 右键文件点击装载出现如下问题■ 绕过TPM CPU硬件限制安装方法■ 虚拟机安装win11 ■ 下载iso文件 选择Windows11 &#xff08;multi-edition ISO&#xff09;在选择中文 ■ 右键文件点击装载出现如下问题 ■ 绕过T…

Socks5代理ip和Https代理ip的区别,该如何选择?

Socks5代理和HTTPS代理都是计算机网络中的代理服务器&#xff0c;它们可以用于在客户端和其他服务器之间建立连接并充当中间人。 两种代理类型都有其优缺点和适用场景。 一、什么是Socks5代理 Socks5代理Socks5代理是一个网络协议&#xff0c;通过该协议可以建立TCP和UDP连接…

RDD算子——转换操作(Transformations )【map、flatMap、reduceByKey】

一、map map 算子 # spark-shell sc.parallelize(Seq(1, 2, 3)).map( num > num * 10).collect()# IDEA Test def mapTest(): Unit {// 1. 创建RDDval rdd1 sc.parallelize(Seq(1, 2, 3))// 2. 执行 map 操作val rdd2 rdd1.map(item > item * 10)// 3. 得到结果val re…

在Kubernetes中优雅地导出和清理Ingress资源

引言 Kubernetes的Ingress资源是定义外部访问集群服务的规则。随着微服务架构和容器化技术的普及&#xff0c;Ingress作为路由流量的关键组件变得愈发重要。当我们需要在环境之间迁移Ingress资源或者备份当前的配置时&#xff0c;就会用到导出功能。然而&#xff0c;直接使用k…

已解决 ValueError: Setting an array element with a sequence. 问题

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…