设计模式之~工厂系列(简单工厂、工厂方法、抽象工厂)

目录

简单工厂模式

工厂方法模式

简单工厂 VS 工厂方法

抽象工厂模式:

拓展:

利用简单工厂模式优化抽象工厂  

利用反射+抽象工厂   进行优化

反射+配置文件+抽象工厂进行优化


简单工厂模式

优点:简单工厂模式的最大优点在于工厂类包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。对与客户端来说去除了与具体产品的依赖。

缺点:违背开发-封闭原则(每增加一个功能类,都要在工厂方法里加逻辑判断)

适用场景:简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

结构图:

实例:(简单工厂和功能类:依赖关系)

工厂方法模式

  • 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

  • 在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。

优点:

  • 工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。

  • 封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。

  • 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

缺点:

  • 类的个数容易过多,增加复杂度。(需要有多个具体工厂)

  • 增加了系统的抽象性和理解难度

适用场景:

  • 当客户程序不需要知道要使用对象的创建过程。

  • 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

结构图:

实例:

简单工厂 VS 工厂方法

  • 工厂方法模式实现时,客户端需要决定实例化哪一个工厂类(子类),选择判断的问题还是存在的。也就是说工厂方法把简单工厂的内部逻辑判断转移到了客户端代码来进行。你想要增加功能,本来是修改工厂类的,而现在是修改客户端。

  • 都集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可以实现,降低了客户程序与产品对象的耦合。

抽象工厂模式:

        抽象工厂模式为创建一组对象提供了一种解决方案。 与工厂方法模式相比, 抽象工厂模式中的具体工厂不只是创建一种具体对象,它负责创建一组(族)具体对象。

优点:

  • 抽象工厂模式隔离了具体类的生成, 使得客户并不需要知道什么被创建。 由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口, 因此只需改变具体工厂的实例, 就可以在某种程度上改变整个软件系统的行为。

  • 当一个族中的多个对象被设计成一起工作时, 它能够保证客户端始终只使用同一个族中的对象。

  • 增加新的族很方便, 无须修改已有系统, 符合“开闭原则”。

缺点:

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂 的接口

  • 增加了系统的抽象性和理解难度。

适用场景:

系统中有多个产品族,而系统一次只可能消费其中一族产品。而这一族产品中每种产品又需要具有不同的创建方法

结构图:

实例:

拓展:

利用简单工厂模式优化抽象工厂  

package 抽象工厂模式;

public class DataAccess {
	private static String db="Sqlserver";
	
	public static IUser CreateUser() {
		IUser result =null;
		switch(db){
		case"Sqlserver":
			result=new SqlserverUser();
			break;
		case"Access":
			result=new AccessUser();
			break;
		}
		return result;
	}
	public static IDepartment CreateDepartment() {
		IDepartment result =null;
		switch(db){
		case"Sqlserver":
			result=new SqlserverDepartment();
			break;
		case"Access":
			result=new AccessDepartment();
			break;
		}
		return result;
	}
}

利用反射+抽象工厂   进行优化

package 抽象工厂模式;
//不在再使用switch-case语句
public class DataAccess1 {
	private static String AssemblyName="抽象工厂模式";
	private static String db="Sqlserver";
	
	public static IUser CreateUser() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		String className=AssemblyName+"."+db+"User";
		return (IUser)Class.forName(className).newInstance();
	}
	public static IDepartment CreateDepartment() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		String className=AssemblyName+"."+db+"Department";
		return (IDepartment)Class.forName(className).newInstance();
	}
}

反射+配置文件+抽象工厂进行优化

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

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

相关文章

计算机专业主要学习什么

2020计算机专业主要学习什么 1计算机专业都学习哪些方面的知识 1、可视化编程 掌握编程方法和可视化技术,熟悉一个可视化平台及其软件开发技术。能够获取Delphi编程人员系列,Java Basic或VB开发专家认证。 就业方向:企业,政府&…

vue前端分页功能怎么实现

Vue前端分页功能可以通过以下几个步骤实现: 1. 安装分页组件库(如vue-pagination-2): bash npm install vue-pagination-2 2. 在Vue项目中引入并注册分页组件: javascript import Vue from vue; import Pagination fr…

传地址给组件并让该组件用到地址在背景图片中的方法

问题 这是我在开发中遇到的问题。在网站的分页面中,背景图片的格式几乎一模一样。只是上面的文字和图片不一样而已。 所以我希望写一个组件,然后页面只需要传入背景图片地址和标题就可以显示出相关内容。 于是我动手写了,大致思路是一个盒…

判断点在多边形内算法的C++实现

本篇博客介绍了使用射线法判断点在多边形内部还是外部的算法,并通过C做了具体实现 1. 算法思路 判断平面内点是否在多边形内有多种算法,其中射线法是其中比较好理解的一种,而且能够支持凹多边形的情况。该算法的思路很简单,就是…

AMEYA360:纳芯微推出车规级耐高压、三线霍尔开关及锁存器NSM101x系列

纳芯微推出全新三线制车规霍尔效应开关/锁存器NSM101x系列,为数字位置检测提供高精度的解决方案,可被广泛应用于汽车执行器等的位置检测。 NSM101x产品系列包含了3个产品型号,即NSM1011(单极霍尔开关)、NSM1012(全极霍尔开关)、NSM1013(霍尔锁…

【Unity】Playable使用细则

【Unity】Playable使用细则 本文基于Unity 2021.3 API。 本文介绍官方文档中没提及的Playable使用限制、注意事项、Bug及规避方案,不是Playable的入门教程! 如果你还不熟悉Playable的基础用法,请先学习以下官方文档和示例: Playa…

基于STM32的定时器--定时中断(HAL库)

基于STM32的定时器--定时中断(HAL库) 介绍引言定时器介绍 实例项目介绍准备设计流程 介绍 引言 本文旨在介绍如何使用STM32CubeMX配置KEIL 5开发一个每10us定时器中断触发一次的项目。帮助初学者入门STM32的定时器使用。 定时器介绍 定时器是STM32微…

chatgpt赋能python:Python升降序排列数字

Python升降序排列数字 在Python编程中,排序是一个非常常见并且重要的操作。Python提供了多种排序算法以满足不同的需求。 排序算法 Python中内置的排序算法有两种:Timsort和Quicksort。其中Timsort是一种混合排序算法,结合了插入排序和归并…

Linux系统中源码安装1.8.x版本Arduino IDE

本文内容参考: Ubuntu22.04安装Arduino IDE及Arduino UNO(使用CH341驱动)调试方法__KILLMILEDC_的博客-CSDN博客 在Linux上下载arduino_不说话的白帽子的博客-CSDN博客 https://guoqing.blog.csdn.net/article/details/88913063?spm1001.…

Linux NGINX服务 ReWrite^location

ReWrite^location 从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。 rewrite 对访问…

c++ new 源码学习一下

之前有一篇文章介绍了 new 的一些用法 c new 在指定内存上创建对象&#xff0c;今天结合源码来学习一下 new 更详细的用法。相关的源码&#xff1a;gcc git 1&#xff0c;void* operator new (std::size_t size); 我们可以在头文件<new>里看到它的原型&#xff1a; _G…

C++11 -- lambda表达式

文章目录 lamaba表达式的引入lambda表达式语法lamabda达式各部分说明捕获列表说明 lamaba表达式底层原理探索 lamaba表达式的引入 在C11之前,如果我们想对自定义类型Goods排序,可以根据姓名,价格,学号按照从大到小或者从小到大的方式排序,可是,这样我们要写额外写6个相关的仿函…

Quest 3初体验,或是苹果MR最大竞争对手

随着苹果MR临近&#xff0c;我们从彭博Mark Gurman了解到更多消息。昨日&#xff0c;Mark Gurman发布了Quest 3上手体验文章&#xff0c;并认为Quest 3可能是苹果MR头显最大的竞争对手。 1&#xff0c;Meta是XR头显领导者 尽管WWDC 23苹果MR将会成为最大的主角&#xff0c;但…

node.js与内置模块

一、目标 能够知道什么是Node.js能够知道Node.js可以做什么能够说出Node.js中的JavaScript的组成部分能够使用fs模块读写操作文件能够使用path模块处理路径能够使用http模块写一个基本的web服务器 二、目录 初始Node.jsfs文件系统模块path路径模块http模块 1.初始Node.js …

macos wireshark 抓取https包

1、启动浏览器 1.1 创建空文件 $ touch /Users/zhujl/Downloads/https/mysslkey.log 2、设置wireshark tls属性&#xff0c;指定tls密钥存储文件 2.1 进入Wireshark Preferfences > Protocols > TLS 属性配置 2.2 勾选上Reassemable TLS records spanning multiple …

设计模式B站学习(一)(java)

这里写目录标题 一、设计模式概述1.1 软件设计模式的产生背景1.2 软件设计模式的概念1.3 学习设计模式的必要性1.4 设计模式分类 二、UML图2.1 类图概述2.2 类图的作用2.3 类图表示法2.3.1 类图表示方法2.3.2 类与类之间关系的表示方法2.3.2.1 关联关系2.3.2.2 聚合关系2.3.2.3…

Selenium的使用

一、基础 1、特点 selenium 是web中基于UI的自动化测试工具&#xff0c;它支持多平台、多语言、多浏览器&#xff0c;还有丰富的API。 2、原理 自动化脚本代码会创建一个http请求发送给浏览器驱动进行解析&#xff0c;浏览器驱动会操控浏览器执行测试&#xff0c;浏览器接着…

ffmpeg编译成wasm

最近在看ffmpeg的源码 https://ffmpeg.xianwaizhiyin.net/ffplay/ https://crifan.github.io/media_process_ffmpeg/website/audio_process/ 做个可运行的例子 代码在找了一堆&#xff0c;可用的版本放在这 https://github.com/killinux/ffmpeg_wasm_demo 先把ffmpeg 编译成 …

内蒙古自治区出台加快充换电基础设施建设实施方案

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

Unity——在C#中调用C++动态链接库(DLL)

一、创建C动态链接库&#xff08;DLL&#xff09; 1、新建C空项目 打开VS&#xff0c;新建一个C空项目&#xff0c;自命名项目名称与位置。 2、配置项目属性为动态链接库 右键项目&#xff0c;点击属性&#xff0c;打开项目属性页&#xff0c;将常规中的配置类型改为动态库&…