重学设计模式-工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)

在平常的学习和工作中,我们创建对象一般会直接用new,但是很多时候直接new会存在一些问题,而且直接new会让我们的代码变得非常繁杂,这时候就会巧妙的用到设计模式,平常我们通过力扣学习的算法可能并不会在我们工作中用到,但设计模式基本上我们所参加的每一个项目都会有。

今天来学习讲解一下工厂模式,这个也是我认为最常见的设计模式之一

1.什么是工厂模式

工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。 我们先从学校食堂窗口案例对工厂模式做个初步的了解:

  1. 没有工厂模式:在没有工厂模式的情况下,我们食堂窗口就类似于米饭,馒头,面条这些都需要我们自己创建,我们需要告诉窗口具体需要什么产品,然后自己创建
  2. 简单工厂模式:在简单工厂模式下,我们就不需要自己创建了,而是让食堂阿姨创建,但是简单工厂模式下只有一个工厂,也就是只有一个窗口,我们需要在这一个窗口选取我们所需要的食物
  3. 工厂方法模式:在工厂方法模式下,每一个食物就对应一个窗口,比如说分为米饭窗口,馒头窗口,面条窗口,我们需要什么仅需要去对应窗口买就可以了
  4. 抽象工厂模式:在抽象工厂模式下,每一个事物可能有多种组成成分,每一个窗口,可以生成多个食品以及食品组成成分,比如说有一个清真窗口,我们需要刀削面加牛肉,或者刀削面加羊肉,就仅需在这一个清真窗口把我们所需的参数传进去,就会我们生成对应的对象。

2.简单工厂模式

简单工厂模式的逻辑就是将定义一个创建对象的接口,将接口的创建和业务逻辑分开,我们需要修改逻辑仅需要去修改工厂里面的内容即可,降低耦合性。

在这里插入图片描述
上面就是简单工厂的uml图,简单工厂由于比较好理解一般来说仅有一个角色就是产品工厂,我们将需要的参数提交给简单工厂,简单工厂就会将产品生产出来。

代码实现:
产品类

abstract class food {public food(){}
}public class noodles extends food {public noodles () {System.out.println("制造-->noodles ");}
}
public class rice extends BMW{public rice (){System.out.println("制造-->rice ");}
}

工厂类:

public class Factory {public food createfood(int type) {switch (type) {case 1:return new rice();case 2:return new noodles();default:break;}return null;}
}

用户类:

public class Users{Factory factory = new Factory();food rice = factory.createfood(1);food noodles = factory.createfood(2);
}

上述之所以用1,2仅仅是为了方便写代码。

简单工厂模式的优缺点都很明显,有点就是解耦,缺点就是我们每次增加或者修改产品都需要去修改工厂类,如果项目规模特别大的话,这显然是无法接受的。

3 工厂方法模式

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

来自小付哥在这里插入图片描述
工厂方法一半分为四个角色
抽象工厂:每个具体工厂需要继承抽象工厂,一般来说用抽象类来实现
具体工厂:需要继承抽象工厂,生产具体产品,一般是具体生产逻辑
抽象产品:具体产品需要继承,有时候也可以没有
具体产品:我们所具体需要的对象

代码示例

产品类:

abstract class food{public food(){}
}
public class noodles extends food{public noodles () {System.out.println("制造-->noodles ");}
}
public class rice extends food{public rice (){System.out.println("制造-->rice ");}
}

工厂类:

interface Factoryfood {BMW createfood();
}public class Factorynoodles implements Factoryfood{@Overridepublic noodles createfood() {return new BMWnoodles();}}
public class Factoryrice implements Factoryfood {@Overridepublic rice createfood() {return new rice();}
}

用户类:

public class Customer {public static void main(String[] args) {Factoryrice factoryrice = new Factoryrice();rice = factoryrice.createrice();Factorynoodles factorynoodles = new Factorynoodles();noodles noodles = factorynoodles.createnoodles();}
}

4.抽象工厂模式

工厂方法模式中,一个工厂生成具体产品,但是正如我文章开头所说,我们所需要的可能不仅仅是一个产品,而是一个产品加某些组件,或者说有几个产品我们需要在一个工厂内生产。此时工厂方法模式就不再适用。

抽象工厂模式提供一个工厂生产多个组件+产品的功能,简单的说一个工厂生产的是一个产品族
在这里插入图片描述

抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
具体产品 Product

抽象工厂相对来说没那么好理解,建议大家阅读一下下面的代码
代码示例:
产品类:


public interface Engine {}  public class EngineA implements Engine{  public EngineA(){  System.out.println("制造-->EngineA");  }  
}  
public class EngineB implements Engine{  public EngineB(){  System.out.println("制造-->EngineB");  }  
}  public interface Aircondition {} public class AirconditionA implements Aircondition{  public AirconditionA(){  System.out.println("制造-->AirconditionA");  }  
}  
public class AirconditionB implements Aircondition{  public AirconditionB(){  System.out.println("制造-->AirconditionB");  }  
} 

工厂类

//创建工厂的接口  
public interface AbstractFactory {  public Engine createEngine();public Aircondition createAircondition(); 
}  public class Factoryrice implements AbstractFactory{     @Override  public Engine createEngine() {    return new EngineA();  }  @Override  public Aircondition createAircondition() {  return new AirconditionA();  }  
}  
//宝马523系列
public class Factorynoodles implements AbstractFactory {  @Override  public Engine createEngine() {    return new EngineB();  }  @Override  public Aircondition createAircondition() {  return new AirconditionB();  }  
} 

用户类:

public class Customer {  public static void main(String[] args){  FactoryBMW320 factoryrice = new Factoryrice();  factoryBMW320.createEngine();factoryBMW320.createAircondition();FactoryBMW523 factorynoodles = new Factorynoodles();  factoryBMW523.createEngine();factoryBMW523.createAircondition();}  
}

5.工厂模式小结

工厂模式主要是通过工厂这个对象来解耦,面对不同需求采用不同的工厂模式,切忌硬套代码模板

工厂模式应该是我们平常用到的最多的设计模式之一,但大家不要盲目去用,有很多用ifelse能够很简单解决的业务也可以不用工厂模式,不然到时候反而增加了我们的代码复杂度。

后面还会持续更新各种设计模式

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

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

相关文章

微服务springboot详细解析(一)

目录 1.Spring概述 2.什么是SpringBoot? 3.第一个SpringBoot程序 4.配置参数优先级 5.springboot自动装配原理 6.SpringBootApplication&SpringApplication.run 7.ConfigurationProperties(prefix "") 8.Validated数据校验 29、聊聊该如何写一…

华为HarmonyOS 让应用快速拥有账号能力 -- 2 获取用户头像昵称

场景介绍 如应用需要完善用户头像昵称信息,可使用Account Kit提供的头像昵称授权能力,用户允许应用获取头像昵称后,可快速完成个人信息填写。以下只针对Account kit提供的头像昵称授权能力进行介绍,若要获取头像还可通过场景化控…

供应链系统设计-何为“前”“中”“后”台系统

概述 大家看文章或交流的时候,经常听到听到XX前台系统、XX中台系统、XX后台系统。而且经常容易混淆并且系统边界定义模糊不清,今天就和大家讨论一下什么是前台、中台和后台系统。 不知道大家对于“康威定律”是否熟悉。在这里简单的给大家介绍一下&…

vue中使用socket.io统计在线用户

目录 一、引入相关模块 二、store/modules 中封装socketio 三、后端代码(nodejs) 一、引入相关模块 main.js 中参考以下代码 ,另外socketio的使用在查阅其它相关文章时有出入,还是尽量以官方文档为准 import VueSocketIO from vue-socket.io import SocketIO from socket.io-…

「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历

本篇将带你实现一个简易日历应用,显示当前月份的日期,并支持选择特定日期的功能。用户可以通过点击日期高亮选中,还可以切换上下月份,体验动态界面的交互效果。 关键词 UI互动应用简易日历动态界面状态管理用户交互 一、功能说明…

【AI系统】推理系统介绍

推理系统介绍 推理系统是一个专门用于部署神经网络模型,执行推理预测任务的 AI 系统。它类似于传统的 Web 服务或移动端应用系统,但专注于 AI 模型的部署与运行。通过推理系统,可以将神经网络模型部署到云端或者边缘端,并服务和处…

Docker 之 bootfs 和 rootfs概述

概述 在 Docker 技术中,理解 bootfs(boot file system)和 rootfs(root file system)的概念对于深入掌握容器技术至关重要。这两个文件系统是 Docker 镜像和容器运行的基础。 bootfs(Boot File System&am…

困扰解决:mfc140u.dll丢失的解决方法,多种有效解决方法全解析

当电脑提示“mfc140u.dll丢失”时,这可能会导致某些程序无法正常运行,给用户带来不便。不过,有多种方法可以尝试解决这个问题。这篇文章将以“mfc140u.dll丢失的解决方法”为主题,教大家有效解决mfc140u.dll丢失。 判断是否是“mf…

M4V 视频是一种什么格式?如何把 M4V 转为 MP4 格式?

M4V 是一种视频文件格式,主要由苹果公司用于其产品和服务中,如 iTunes Store 上的电影和电视节目。这种格式可以包含受版权保护的内容,并且通常与苹果的 DRM(数字版权管理)技术结合使用,以限制内容的复制和…

VS打开UI文件失败

选择一个UI文件,右键打开方式,要自己添加路径 然后选择自己的QT Creator路径 可以参考我的去找一下:"C:\Qt\Qt5.14.2\Tools\QtCreator\bin\qtcreator.exe"

网络编程(UDP\TCP回显服务器)

目录 套接字socket TCP和UDP特点比较 特点 比较 UDP回显服务器/客户端的编写 UDP的socket api 回显服务器 客户端 TCP回显服务器/客户端的编写 TCP的socket api 回显服务器 客户端 优化服务器 1.关闭服务器创建的socket对象 2.引入线程池,为多个客户…

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验三----学校选址与路径规划(超超超详细!!!)

目录 实验三 学校选址与道路规划 3.1 实验内容及目的 3.1.1 实验内容 3.1.2 实验目的 3.2 实验方案 3.3 操作流程 3.3.1 环境设置 3.3.2 地势分析 (1)提取坡度: (2)重分类: 3.3.3 学校点分析 (1)欧氏距离: (2)重分类: 3.3.4 娱乐场所点分析 (1)欧氏距离…

【Delphi】modbus-TCP 协议库

在日常开发中,也会遇到使用modbus的部件,比如温度控制器、读卡器等等,那么使用Delphi开发,也就必须遵守modbus-TCP协议,如果自己使用TCP控件写也没有问题,不过如果有开源的三方库,别人已经调试过…

计算机网络-网络安全

网络安全介绍 端口扫描 安全包括那些方面: 数据存储安全、应用程序安全、操作系统安全、网络安全、物理安全、用户安全教育 一、网络安全问题概述 1. 计算机网络面临的安全性威胁 计算机网络上的通信面临以下的四种威胁: 截获——从网络上窃听他人…

GEE Download Data——气温数据的下载

GEE数据下载第二弹!今天我们来分享气温数据的下载。 一、数据介绍 气温数据我们要用到的是MODIS数据产品,MOD11A2 V6.1 产品提供 1200 x 1200 公里网格内 8 天平均陆地表面温度 (LST)。 MOD11A2 中的每个像素值都是该 8 天内收集的所有相应 MOD11A1 LST 像素的简单平均值。…

【第 1 章 初识 C 语言】1.8 使用 C 语言的 7 个步骤

目录 1.8 使用 C 语言的 7 个步骤 1.8.1 第 1 步:定义程序的目标 1.8.2 第 2 步:设计程序 1.8.3 第 3 步:编写代码 1.8.4 第 4 步:编译 1.8.5 第 5 步:运行程序 1.8.6 第 6 步:测试和调试程序 1.8.…

docker部署RustDesk自建服务器

客户端: Releases rustdesk/rustdesk GitHub 服务端: 项目官方地址:GitHub - rustdesk/rustdesk-server: RustDesk Server Program 1、拉取RustDesk库 docker pull rustdesk/rustdesk-server:latest 阿里云库: docker pu…

通义灵码走进北京大学创新课堂丨阿里云云原生 10 月产品月报

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》,从趋势热点、产品新功能、服务客户、开源与开发者动态等方面,为企业提供数字化的路径与指南。 趋势热点 🥇 通义灵码走进北京大学创新课堂,与 400…

Java基础面向对象(String类)

String 特点 是内存中常量, 值在内存中一旦创建, 不可改 更改String类型引用的值本质上是将引用指向了一个新的字符串地址 String s1 "abc";String s2 s1;//引用s1的地址赋值给了s2 ​s2 "edf";//让s2指向新字符串 ​System.out.println("s1: &q…

【C++】深入优化计算题目分析与实现

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯第一题:圆的计算我的代码实现代码分析改进建议改进代码 老师的代码实现代码分析可以改进的地方改进代码 💯第二题:对齐输出我的代码实现…