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

写在前面:本文是个人在学习设计模式时的所思所想,汇总了其他博主及自己的感悟思考,可能存在出入,请大家理性食用~~

工厂模式

在工厂模式中,父类决定实例的生成方式,但并不决定所要生成的具体的类具体的处理全部交给子类负责。这样就可以将生成实例的框架和实际负责生成实例的类解耦。

核心:

  • 实例化对象不使用new,用工厂方法创建对象。
  • 使用工厂统一管理对象的创建,将调用者跟实现类解耦。

1.1. 简单工厂模式

简单工厂模式又叫静态工厂方法模式(因为工厂类定义了一个静态方法)

简单工厂模式的角色包括三个

  • 抽象产品角色
  • 具体产品角色
  • 工厂类角色

  • 抽象产品角色:
public interface Weapon{//所有的武器都有攻击行为public void attack();
}
  • 具体产品角色:
//坦克(具体产品角色)
public class Tank implements Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
}
// 战斗机(具体产品角色)
public class Fighter implements Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
}
//匕首(具体产品角色)
public class Dagger implements Weapon{@Overridepublic void attack() {System.out.println("砍他丫的!");}
}
  • 工厂类角色:
//工厂类角色
public class WeaponFactory {/*** 根据不同的武器类型生产武器* @param weaponType 武器类型* @return 武器对象*/public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();} else if ("DAGGER".equals(weaponType)) {weapon = new Dagger();} else {throw new RuntimeException("不支持该武器!");}return weapon;}
}
  • 测试类:
public class Client {public static void main(String[] args) {Weapon weapon1 = WeaponFactory.get("TANK");weapon1.attack();Weapon weapon2 = WeaponFactory.get("FIGHTER");weapon2.attack();Weapon weapon3 = WeaponFactory.get("DAGGER");weapon3.attack();}
}

优点:实例化具体对象不需要关系具体细节,直接根据参数从工厂索要即可,初步实现了责任的分离。客户端只负责“消费”,工厂负责“生产”。生产和消费分离。

缺点

    • 工厂类集中负责所有的创造逻辑,不能出问题,一旦出问题,整个系统瘫痪。
    • 不符合OCP开闭原则,在进行系统拓展时,需要修改工厂类。

1.2. 工厂方法模式

工厂方法模式既保留了简单工厂的优点,同时又解决了简单工厂的缺点。

工厂方法模式的角色包括四个

  • 抽象工厂角色
  • 具体工厂角色
  • 抽象产品角色
  • 具体产品角色

  • 抽象产品角色:
//武器类(抽象产品角色)
public abstract class Weapon {//所有武器都有攻击行为public abstract void attack();
}
  • 具体产品角色:
//具体产品角色
public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
}
//具体产品角色
public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机发射核弹!");}
}
  • 抽象工厂角色:
//武器工厂接口(抽象工厂角色)
public interface WeaponFactory {Weapon get();
}
  • 具体工厂角色:
public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();}
}
public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();}
}
  • 客户端程序:
public class Client {public static void main(String[] args) {//实例化不同的工厂WeaponFactory factory = new GunFactory();Weapon weapon = factory.get();weapon.attack();WeaponFactory factory1 = new FighterFactory();Weapon weapon1 = factory1.get();weapon1.attack();}
}

如果想扩展一个新的产品,只要新增一个产品类,再新增一个该产品对应的工厂即可,例如新增:匕首

public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍丫的!");}
}
public class DaggerFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Dagger();}
}
  • 客户端程序:
public class Client {public static void main(String[] args) {//实例化不同的工厂WeaponFactory factory = new GunFactory();Weapon weapon = factory.get();weapon.attack();WeaponFactory factory1 = new FighterFactory();Weapon weapon1 = factory1.get();weapon1.attack();WeaponFactory factory2 = new DaggerFactory();Weapon weapon2 = factory2.get();weapon2.attack();}
}

因此可以看出在进行功能拓展时,不需要修改之前的源码,显然工厂方法模式更符合OCP原则。

优点

    • 拓展性高,如果想增加一个产品,只需新增一个产品类及其对应的工厂类即可。
    • 弱化抽象工厂的职责,将具体产品的实现交给其他工厂,职责分工明确。

缺点

    • 每次再新增一个产品时,都需要增加一个具体类及其对应的工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

在Spring框架中,BeanFactory使用的是工厂方法模式

源码位置:

抽象工厂角色Bean Factory:

实现BeanFatory的具体工厂:

实现BeanFatory的具体工厂角色:

1.3. 抽象工厂模式

抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。

抽象工厂方法模式的角色也包括四个

  • 抽象工厂角色
  • 具体工厂角色
  • 抽象产品角色
  • 具体产品角色

类图:

其他实现原理和流程同工厂方法模式。只不过抽象工厂中包含很多个具体的功能,是一个超级工厂父类。

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

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

相关文章

[终端安全]-7 后量子密码算法

本文参考资料来源:NSA Releases Future Quantum-Resistant (QR) Algorithm Requirements for National Security Systems > National Security Agency/Central Security Service > Article Commercial National Security Algorithm Suite 2.0” (CNSA 2.0) C…

领域驱动设计DDD

为什么要DDD 传统MVC 传统的MVC模型框架拆分成了三层:显示层、控制层、模型层。显示层负责显示用户界面,控制层负责处理业务逻辑、而模型则负责与数据库通信,对数据进行持久化的操作。从代码角度来看,这样的框架结构每个模块职责…

【漏洞复现】WordPress插件Recall CVE-2024-32709 SQL注入漏洞

0x01 产品简介 WordPress是一款免费开源的内容管理系统(CMS),最初是一个博客平台,但后来发展成为一个功能强大的网站建设工具,适用于各种类型的网站,包括个人博客、企业网站、电子商务网站等,并逐步演化成一款内容管理…

小白学c嘎嘎(第二天)入门基础下

温馨提醒:本篇文章起,文章内容排版将更新,层层深入 基础知识 回顾 引用的语法格式:类型& 引⽤别名 引⽤对象; 引用特性 1. 引⽤在定义时必须初始化 2. ⼀个变量可以有多个引⽤ 3. ⼀旦引⽤⼀个实体,再不…

STM32(二):STM32工作原理

0、参考1、寄存器和存储器基本概念(1)基本概念(2)主要区别(3)联系(4)实际应用中的案例(5)总结(6)一些名词解释 2、STM32指南者板子-存…

ArcGis将同一图层的多个面要素合并为一个面要素

这里写自定义目录标题 1.加载面要素的shp数据 2.点击菜单栏的地理处理–融合,如下所示: 3.将shp面要素输入,并设置输出,点击确定即可合并。合并后的属性表就只有一个数据了。

怎样卸载电脑上自带的游戏?

卸载电脑上自带的游戏通常是一个简单的过程,以下是几种常见的方法,您可以根据自己的操作系统版本选择相应的步骤进行操作: 方法一:通过“设置”应用卸载(适用于Windows 10和Windows 11) 1. 点击开始菜单&…

设计模式之外观模式(Facade)

Facade设计模式,也称为外观模式,是一种结构型设计模式,它主要用于为子系统中的一组接口提供一个统一的高层接口,从而使得子系统更加容易使用。以下是关于Facade设计模式的详细介绍: 一、定义 Facade模式为多个复杂的…

基于Android平台开发,购物商城

1. 项目功能思维导图 2. 项目涉及到的技术点 使用SQLite数据库实现数据存储使用CountDownTimer实现启动页倒计时使用SharedPreferences实现记住密码登录使用BottomNavigationView实现底部导航栏使用ActivityFragment实现底部导航栏页面之间切换使用RecyclerViewadapter实现商品…

无人机之穿越机注意事项篇

一、检查设备 每次飞行前都要仔细检查穿越机的每个部件,确保所有功能正常,特别是电池和电机。 二、遵守法律 了解并遵循你所在地区关于无人机的飞行规定,避免非法飞行。 三、评估环境 在飞行前检查周围环境,确保没有障碍物和…

在openSUSE-Leap-15.6-DVD-x86_64下停用USB无线网卡驱动rtw88_8822bu改用rtl88x2bu

在openSUSE-Leap-15.6-DVD-x86_64下停用USB无线网卡驱动rtw88_8822bu改用rtl88x2bu 一、openSUSE-Leap-15.6-DVD-x86_64自带USB无线网卡驱动rtw88_8822bu能够正常上网但不能让USB无线网卡内置小灯闪蓝光 当有数据流量通过USB无线网卡,其内置小灯会不断闪蓝光的&…

前端复刻百度网址精简版HTML+CSS

案列图&#xff1a; 自制效果图&#xff1a; 源代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…

雷达视频采集卡 HPx-410

产品简介 雷达视频采集卡 HPx-410&#xff0c;应用于接入导航雷达数据&#xff0c;导航雷达视频&#xff0c;适用于JRC雷达、古野furuon雷达、Sperry雷达等多种型号的雷达。 HPx-410 可以接入导航雷达数据&#xff0c;引入导航雷达原始回波&#xff0c;然后将雷达视频采集到计…

如何用IP地址申请SSL证书实现网络安全

互联网是一个全球性的网络&#xff0c;它将世界各地的计算机系统和设备连接在一起。在这个庞大的网络中&#xff0c;每个设备都需要一个唯一的标识符&#xff0c;即IP&#xff08;Internet Protocol&#xff09;地址&#xff0c;以便其他设备能够找到并与其通信。然而&#xff…

C# + halcon 联合编程示例

C# halcon 联合编程示例 实现功能 1.加载图像 2.画直线&#xff0c;画圆&#xff0c;画矩形, 画椭圆 ROI&#xff0c;可以调整大小和位置 3.实现找边&#xff0c;找圆功能 效果 开发环境 Visual Studio 2022 .NET Framework 4.8 halcondotnet.dll 查看帮助文档 项目结构 DL…

探索东芝 TCD1304DG 线性图像传感器的功能

主要特性 高灵敏度和低暗电流 TCD1304DG 具有高灵敏度和低暗电流&#xff0c;非常适合需要精确和可靠图像捕捉的应用。传感器包含 3648 个光敏元件&#xff0c;每个元件尺寸为 8 m x 200 m&#xff0c;确保了出色的光灵敏度和分辨率。 电子快门功能 内置的电子快门功能是 T…

力扣爆刷第162天之TOP100五连刷76-80(最小路径和、最长公共前缀、最长连续序列)

力扣爆刷第162天之TOP100五连刷76-80&#xff08;最小路径和、最长公共前缀、最长连续序列&#xff09; 文章目录 力扣爆刷第162天之TOP100五连刷76-80&#xff08;最小路径和、最长公共前缀、最长连续序列&#xff09;一、64. 最小路径和二、221. 最大正方形三、162. 寻找峰值…

mysql判断时间段是否重合

mysql判断时间段是否重合 SELECT CASE WHEN t1.start_time < t2.end_time AND t1.end_time > t2.start_time THEN ‘重合’ ELSE ‘不重合’ END AS result FROM table_name t1, table_name t2 WHERE t1.id <> t2.id;

14-26 剑和侠客 – 预训练模型三部曲3 – 机器人时代来临

概述 在第 1 部分和第 2 部分中&#xff0c;我们讨论了适用于文本和图像任务的预训练模型&#xff0c;并探索了当今常用的模型。我们分析了这些模型的架构以及如何将它们用于特定任务。实现 AGI 所需的两个主要支柱是语言理解和机器的视觉能力。有许多任务与这两种能力有关。 …

中职网络安全B模块渗透测试system0016

访问http://靶机IP/web1/,获取flag值&#xff0c;Flag格式为flag{xxx}&#xff1b; 可能会跳转8000端口删除进入80端口 进入后点击侦查一下&#xff0c;这里乱码了&#xff0c;我们点击查看是一个柯南&#xff0c;web但这是一个web题目肯定不是隐写术&#xff0c;所以说题目的…