让你快速理解工厂模式

news/2024/4/25 9:41:21/文章来源:https://blog.csdn.net/weixin_42957931/article/details/126650513

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

  • 前言
  • 一、简单工厂
    • 定义
    • 代码示例
    • 优缺点
  • 二、工厂方法
    • 定义
    • 代码示例
      • 工厂基类
      • 具体工厂
      • 客户端
    • 优缺点
  • 三、抽象工厂
    • 定义
    • 类图:
    • 具体实现思路(代理示例)
      • 1,定义形状和颜色两个接口,具体的形状和颜色各自实现其接口。
      • 2,定义抽象工厂,里面有抽象形状和抽象颜色方法。
      • 3,形状工厂类和颜色工厂类实现抽象工厂类,实现自己的业务逻辑。
      • 4,创建工厂构造器(通过参数来决定获取其产品实例)
      • 5)客户端
    • 优缺点


前言

`
工厂模式分为简单工厂(不包含在23个设计模式之中)、工厂方法、抽象方法;这里我将以最简单的方式来总结讲解这三者的区别,如果你想快速的了解这三者模式的具体用法、优缺点请继续往下阅读!

一、简单工厂

定义

三个角色:工厂类、抽象产品类、具体产品类
简单工厂实现原理:
1)定义一个工厂,客户端只需要传相应参数,即可从该工厂获取对象,不用关心对象具体产品时怎么创建的;
2)工厂类负责去根据参数创建对象

代码示例

如下所示简单工厂类:

publicclass PhoneFactory {public static Phone createPhone(String type) {Phone phone = null;if ("huawei".equals(type)) {phone = new Huawei();} elseif ("xiaomi".equals(type)) {phone = new Xiaomi();} elseif ("apple".equals(type)) {phone = new IPhone();} else {System.out.println("暂不支持");}return phone;}
}

优缺点

优点:
1)松耦合,用户不需要知道具体实现的类,只需要传入具体的参数就能获取想要的对象。
缺点:
1)不符合开闭原则,当新增加产品时需要修改工厂类。
2)当具体实现产品较多时,if…else会比较多导致代码不美观

工厂方法可以解决这两个问题

二、工厂方法

定义

角色:工厂基类、具体产品工厂、抽象产品、具体产品
跟简单工厂一类似,只不过将工厂形式改为了工厂基类+具体产品工厂的组合;工厂里不再负责创建对象了。而是利用依赖倒置原则来获取要调用的具体对象。

代码示例

工厂基类

publicinterface PhoneFactory {Phone createPhone();
}

具体工厂

publicclass HuaweiFactory implements PhoneFactory {@Overridepublic Phone createPhone() {returnnew Huawei();}
}

客户端

 public static void main(String[] args) {PhoneFactory phoneFactory = new XiaomiFactory();Phone phone = phoneFactory.createPhone();phone.play()}

优缺点

优点:
1)不需要通过参数去判断获取相应的产品
2)减少了简单工厂中的if…else多问题
3)符合开闭原则,做到了产品类和工厂类代码的完全解耦;当新增产品时,不需要修改工厂类方法,只需要新增产品工厂即可

缺点:新增产品时,需要同时新增产品和产品工厂类,成对增加了,导致了系统的复杂度。

三、抽象工厂

定义

在工厂模式的基础上进行了向上的扩展,它将具有一定共性的产品放到一起,由工厂类为这些产品提供共性的调用方法,再由调用者根据自己的需求调用对应的工厂类去实现获取产品实例。

类图:

为了更好的理解抽象工厂模式,这里我放了一张有关颜色和形状的类图:
在这里插入图片描述

以下解释是帮助理解这张类图的:
    1)形状和颜色看似不通的业务,由一个工厂生产出来
    2)形状:方形、圆形除都是形状外,都有自己各自的实现方法
    3)颜色:红色、蓝色、绿色除了都是颜色外,还有各自自己的实现方法

具体实现思路(代理示例)

1,定义形状和颜色两个接口,具体的形状和颜色各自实现其接口。

形状

public interface Shape {void draw();
}

//方形

public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}

//圆形

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}
}

颜色

public interface Color {void fill();
}

//红色

public class Red implements Color {@Overridepublic void fill() {System.out.println("Inside Red::fill() method.");}
}

//蓝色

public class Blue implements Color {@Overridepublic void fill() {System.out.println("Inside Blue::fill() method.");}
}

2,定义抽象工厂,里面有抽象形状和抽象颜色方法。

public abstract class AbstractFactory {public abstract Color getColor(String color);public abstract Shape getShape(String shape);
}

3,形状工厂类和颜色工厂类实现抽象工厂类,实现自己的业务逻辑。

形状抽象类

public class ShapeFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){if(shapeType == null){return null;}        if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();}return null;}@Overridepublic Color getColor(String color) {return null;}
}

颜色抽象类

public class ColorFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){return null;}@Overridepublic Color getColor(String color) {if(color == null){return null;}        if(color.equalsIgnoreCase("RED")){return new Red();} else if(color.equalsIgnoreCase("BLUE")){return new Blue();}return null;}
}

4,创建工厂构造器(通过参数来决定获取其产品实例)

public class FactoryProducer {public static AbstractFactory getFactory(String choice){if(choice.equalsIgnoreCase("SHAPE")){return new ShapeFactory();} else if(choice.equalsIgnoreCase("COLOR")){return new ColorFactory();}return null;}
}

5)客户端

 public static void main(String[] args) {//1,获取形状工厂AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");//获取形状为 Circle 的对象Shape shape1 = shapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//2,获取颜色工厂AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");//获取颜色为 Red 的对象Color color1 = colorFactory.getColor("RED");//调用 Red 的 fill 方法color1.fill();}

优缺点

优点:将一定共性的产品集中在一起,能保证始终使用的都是一个产品族中的对象。
缺点:降低了系统的扩展性,当新增产品时需要在抽象类中增加,也要在实现类中增加,较为复杂。

如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。

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

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

相关文章

java面试题总结

1.java基础 1.1java的概述 1.1.1java的基本数据类型和引用数据类型 基本数据类型:byte、short、int、long、float、double、char、boolean 引用数据类型: String,以及其他的类型 自动类型转换:从低级别到高级别,系…

使用dom4j xml解析文件数据

XML <?xml version="1.0" encoding="ISO-8859-1"?> <contactList><contact id="1" vip="true"><name> 潘金莲 </name><gender>女</gender><email>panpan@itcast.cn</email>&…

猿创征文|在工作中彻底搞懂原型和原型链的原理

前言 在前端开发过程中&#xff0c;涉及到JS原理相关的内容也就是常用的几大模块&#xff0c;不仅常用而且很重要&#xff0c;但是涉及到原理的话会有点难懂&#xff0c;尤其是对JS接触不太久的开发者来讲&#xff0c;甚至工作好几年的开发者也只是在平时开发中知道怎么使用&am…

FastFlow介绍与farm模式例子的编写

软件简介 FastFlow 是一个多核编程框架&#xff0c;实现了无锁的 MPMC FIFO 队列规范&#xff0c;用以支持多核的高级应用开发。速度比 TBB、OpenMP 都要快。 主页&#xff1a; https://github.com/fastflow/fastflow Farm模式的编写&#xff1a; 1.基本Farm模式编写 #inclu…

推荐系统-Hive基础

Hive基本操作基本概念功能说明架构hive和hadoop数据模型安装部署安装启动基本操作hive的内部表和外部表分区表动态分区Hive函数Hive内置运算符和内置函数Hive自定义函数综合案例基本概念 功能说明 操作接口采用类SQL法&#xff0c;提供快速开发的能力避免了去写MapReduce&…

通信原理 | 基本概念:信源、信道、噪声、信宿等

一、通信的基本概念 1. 信源 通信中产生和发送信息的一端叫做信源 2. 信宿 通信中接收信息的一端叫做信宿 3. 信道 信号在信源和信宿之间传输的通道叫做信道(主要分为有线信道和无线信道) 4. 噪声 信息在传输过程中可能受到外界干扰&#xff0c;把这种干扰成为噪声 5.…

关于Flask高级_RequestParser中的add_argument方法参数详解

Flask高级_RequestParser中的add_argument方法参数详解 一.参数介绍 default&#xff1a;默认值&#xff0c;如果这个参数没有值&#xff0c;那么将使用这个参数 指定的默认值。 required&#xff1a;是否必须。默认为False&#xff0c;如果设置为True&#xff0c;那么这 个参…

msf后渗透之文件交互指令、上传下载文件、屏幕截图、键盘记录、创建账户、音频录像和提权(上)

目录 1、文件交互指令 2、上传下载文件(windows) 3、屏幕截图(windows) 4、键盘记录&#xff08;windows&#xff09; 1、先启动记录keyscan_start 2、显示键盘输入内容keyscan_dump 3、结束监控keyscan_stop 5、创建账户&#xff08;windows&#xff09; 1、先看下目标…

C语言-手写Map(数组+链表+红黑树)(全功能)

要求 需要准备数组集合(List) 数据结构需要准备单向链表(Linked) 数据结构需要准备红黑树(Rbtree)数据结构需要准备红黑树和链表适配策略(文章内部提供,可以自行参考) 建议先去阅读我博客这篇文章C语言-手写Map(数组链表)(全功能) 有助于理解 hashmap使用红黑树的原因是&…

Java实现的一个编译器源代码(Win11)

本文的源代码摘自编译器龙书《Compilers : principles, techniques, and tools》第二版的附录A“一个完整的前端”&#xff08;A Complete Front End&#xff09;。 上述书中的编译器是在Unix系统中&#xff0c;主体代码与书中相同&#xff0c;只是对字符串处理不同&#xff1…

C++ Qt / VS2019 +opencv + onnxruntime 部署语义分割模型【经验】

本机环境&#xff1a; OS:WIN11 CUDA: 11.1 CUDNN:8.0.5 显卡&#xff1a;RTX3080 16G opencv:3.3.0 onnxruntime:1.8.1 目前C 调用onnxruntime的示例主要为图像分类网络&#xff0c;与语义分割网络在后处理部分有很大不同。 pytorch模型转为onnx格式 1.1 安装onnx, 参考官网…

Tcp通信

一发一收 Client package tcpDemo;import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {//1.创建Socke通信管道请求服务端的连接//p…

TCP连接管理机制(超级重要)

以下是这篇文章讲解的思维导图,整理完,我也脑瓜子嗡嗡的,怎么这么多,那是因为太重要了,防止面试官把你问死,那就必须去了解,加油啊~~~ 参考 : 小林coding 书籍 : TCP/IP 卷一 网站 : 计算机网络-41-60 | 阿秀的学习笔记 知乎文章 : 看到有人说&#xff0c;只看到过TCP状态位…

【单片机原理及应用】第一篇——单片机概述

个人主页 点击这里 专栏学习 点击这里 目录 内容概要 1.1单片机简介 1.2单片机的发展历史 1.3单片机的特点 1.4单片机的应用 1&#xff0e;工业检测与控制 2&#xff0e;仪器仪表 3&#xff0e;消费类电子产品 4&#xff0e;通讯 5&#xff0e;武器装备 6.各种终…

python从入门到实践:数据类型、文件处理

目录 一、数据类型 1.数字 整型与浮点型 其他数字类型 2.字符串 3.字节串 4.列表 5.元祖 6.集合 7.字典 8.可变类型与不可变类型 数字类型 字符串 列表 元祖 字典 9.数据类型总结 二、文件处理 1.文件的引入 2.文件的基本操作流程 2.1基本流程 2.2资源回…

【Java 基础】7、学习 Java 中的方法(方法的定义、可变参数、参数的传递问题、方法重载、方法签名)通过官方教程

&#x1f4b0; 写了一段时间的 Java 程序&#xff0c;SpringBoot &#x1f343;项目也做了好几个&#xff0c;但感觉自己对 Java 的了解还是特别少&#xff0c;所以决定从零&#x1f37c;开始重新学习&#xff0c;下面是学习的笔记。【学习素材&#xff1a;韩顺平老师】 &#…

docker 安装 elasticsearch

一、安装docker Docker 的安装_傲傲娇的博客-CSDN博客 二、配置es挂载文件和目录 mkdir -p /opt/elasticsearch/{config,data,plugins} chmod 777 /opt/elasticsearch/data 在config目录下创建elasticsearch.yml配置文件 cluster.name: elasticsearch-cluster # 节点名称 n…

【MC教程】iPad启动Java版mc(无需越狱)(保姆级?) Jitterbug启动iOS我的世界Java版启动器 PojavLauncher

【MC教程】iPad启动Java版mc&#xff08;无需越狱&#xff09;(保姆级?) Jitterbug启动iOS我的世界Java版启动器 PojavLauncher 文章目录【MC教程】iPad启动Java版mc&#xff08;无需越狱&#xff09;(保姆级?) Jitterbug启动iOS我的世界Java版启动器 PojavLauncher前言iSign…

springmvc实现文件上传书本管理CRUD

今天小编给大家分享文件上传&#xff0c;和对书本管理进行新增、修改、删除、查询。 效果展示 首页 新增 修改 一、书本管理CRUD 1.开发前必做的配置 1.1 导入pom.xml文件依赖 实现CRUDspringmvc的jar包 <dependency><groupId>org.springframework</groupId…

3.实现redis哨兵,模拟master故障场景

3.实现redis哨兵,模拟master故障场景 实验拓扑图 3.1 哨兵的准备实现主从复制架构 哨兵的前提是已经实现了一个redis的主从复制的运行环境,从而实现一个一主两从基于哨兵的高可用redis架构。 注意: master 的配置文件中的masterauth 和slave的都必须相同 所有主从节点的redis…