程序猿成长之路之设计模式篇——创建型设计模式——抽象工厂模式

news2024/10/25 23:30:49

设计模式开篇之作,简单介绍一下抽象工厂设计模式

前言

试想一下,国内有两个工厂,工厂1和工厂2,这两个不同牌子的工厂生产同样类型的商品,但是商品的价格和数量不一致,这时候我们要对其进行设计,该如何设计呢?

设计思路

  1. 首先我们需要抽离出两个工厂的共性形成一个抽象类,AbstractFactory其中有两个方法,生产产品A和产品B,也就是CreateProductA() 和CreateProductB()之后通过继承的方式创建两个工厂类,ConcreteFactory1 和ConcreteFactory2,同样继承了这两个方法。
  2. 其次我们需要对产品进行抽象,针对不同的产品创建不同的抽象类,里面可以配置价格、数量等参数,也可以配置一些抽象方法。然后根据工厂类去编写产品的实现类。也就是ProductA1、ProductA2、ProductB1、ProductB2
  3. 接下来我们在ConcreteFactory1 工厂中的CreateProductA和CreateProductB方法里分别创建ProductA1和ProductB1,也就是代表了工厂1生产的产品A和产品B,同样的操作适用于ConcreteFactory2 工厂
  4. 最后调用时,我们先创建抽象工厂的实现类也就是先创建工厂1或者工厂2的实例对象,然后通过调用CreateProductA或者CreateProductB方法去生成该工厂的产品类。
    在这里插入图片描述
    抽象工厂(Abstract Factory):
    核心,与商业逻辑无关
    具体工厂(Concrete Factory):
    在客户端的调用下创建产品的实例,含有选择合适的产品对象的逻辑(与商业逻辑有关)
    抽象产品(Abstract Product):
    担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
    具体产品(Concrete Product):
    抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

代码实现

冰箱抽象类

/**
 * 冰箱抽象类。
 * @author zygswo
 *
 */
public abstract class Fridge {
	public abstract void sell(); //销售
	public abstract void saveFood(); //保存食物
}

海尔冰箱实现类

public class HaierFridge extends Fridge{

	@Override
	public void sell() {
		System.out.println("海尔 冰箱出售");
	}

	@Override
	public void saveFood(Food food) {
		System.out.println("海尔 冰箱保存了食物");
	}
}

美的冰箱实现类

public class MediaFridge extends Fridge{

	@Override
	public void sell() {
		System.out.println("美的 冰箱出售");
	}

	@Override
	public void saveFood() {
		System.out.println("美的 冰箱保存了食物");
	}
}

洗衣机抽象类

/**
 * 洗衣机抽象类。
 * @author zygswo
 *
 */
public abstract class WashingMachine {
	public abstract void sell(); //销售
	public abstract void washClothes(); //保存食物
}

海尔洗衣机实现类

public class HaierWashingMachine extends WashingMachine{

	@Override
	public void sell() {
		System.out.println("海尔  洗衣机出售");
	}

	@Override
	public void washClothes(Cloth cloth) {
		System.out.println("海尔  洗衣机洗" + cloth.getName());
	}
}

美的洗衣机实现类

public class MediaWashingMachine extends WashingMachine{

	@Override
	public void sell() {
		System.out.println("美的  洗衣机出售");
	}

	@Override
	public void washClothes(Cloth cloth) {
		System.out.println("美的  洗衣机洗" + cloth.getName());
	}
}

工厂抽象类

public interface ApplianceManufacturer {
	Fridge createFridge();
	WashingMachine createWashingMashine();
}

海尔工厂类

public class HaierFactory implements ApplianceManufacturer{

	@Override
	public Fridge createFridge() {
		return new HaierFridge();
	}

	@Override
	public WashingMachine createWashingMashine() {
		return new HaierWashingMachine();
	}
	
}

美的工厂类

public class MediaFactory implements ApplianceManufacturer{

	@Override
	public Fridge createFridge() {
		return new MediaFridge();
	}

	@Override
	public WashingMachine createWashingMashine() {
		return new MediaWashingMachine();
	}
}

主函数

public class MainEntrance {

	public static void main(String[] args) {
		Fridge haierFridge = new HaierFactory().createFridge();
		haierFridge.sell();
		haierFridge.saveFood();
		Fridge mediaFridge = new MediaFactory().createFridge();
		mediaFridge.sell();
		mediaFridge.saveFood();
	}
}

抽象工厂的优缺点

优势:

  1. 创建新的产品族,支持“对扩展开放,对修改关闭”的原则。
  2. 满足不同的工厂生成不同的商品的功能需求。
  3. 实现了产品和工厂的解耦,产品的功能可以统一配置。
    劣势:
  4. 如果需要调整新增产品的功能,需要修改所有工厂产品实现类,会比较繁琐。

应用场景

  1. 应用于一个系统有多个产品族,且系统只消费其中一个或多个产品族
  2. 应用于不需要了解产品实现细节,只需要知道产品工厂和产品名称。

其他两种工厂模式

简单工厂
通过往工厂类传参来判断生成哪个具体产品类。
例子: 如图所示,运算类为抽象产品类,加法、减法、乘法、除法类为具体产品类,往createOperate(String opeName) 传参,通过传入的参数opeName来判断该生成哪个具体产品类。之后调用产品类的GetResult方法来获取结果。
在这里插入图片描述
优点:简单易懂,适用于产品数量较少的场景
缺点:不满足开闭原则,如果有新的产品要配置就要修改工厂类。

工厂方法:
将具体的产品类生成逻辑交给抽象工厂类的子类来实现,一个工厂类对应一个产品类,以上述的运算工厂为例,工厂方法设计模式如下图:
在这里插入图片描述
优点:适用于产品数量较多的场景,满足开闭原则,如果有新的产品要配置可以新增工厂类和产品类。
缺点:如果抽象产品类需要添加新的运算,改动较大。

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

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

相关文章

Centos基线自动化检查脚本

此脚本是一个用于检查Linux系统安全配置的Bash脚本。它通过多项安全标准对系统进行评估,主要检查以下内容: IP地址获取:脚本首先获取主机的IP地址,确保其以10.115开头。 密码策略检查: 检查最小密码长度(P…

解析 wxPython 和 Pandas 实现的 XLSX 分析器和网页打开器

在本文中,我们将分析一个使用 wxPython 和 Pandas 库编写的 Python 应用程序,名为 “XLSX Analyzer and Web Opener”。该应用程序的核心功能是:从 Excel 文件中读取数据并显示在网格中,此外,还允许用户使用 Google Ch…

力扣面试150 汇总区间 双指针 StringBuilder

Problem: 228. 汇总区间 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.ArrayList; import java.util.List;class Solution {public List<String> summaryRanges(int[] nums) {List<String> ret new ArrayList<String>(); // 存储结果的列表in…

Faster R-CNN模型微调检测航拍图像中的小物体

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

【排序算法】选择排序的全面剖析(含详细图解)

在之前文章中我们了解到了插入排序&#x1f449;【插入排序】&#xff0c;现在我们来学习排序算法中的直接选择排序。 目录 &#x1f4af;引言 &#x1f4af;选择排序的原理 &#x1f4af;选择排序的实现步骤 ⭐简单选择排序&#xff08;以升序为例&#xff09; ⭐代码实…

Human-M3 多模态姿态估计数据集-初步解读

文章概述(个人总结):该论文重点提出一个用于人体姿态估计的RGB+点云数据集,针对该多模态数据集,作者阐述了数据集的收集、数据标注以及该数据集的特点。并提出了一个简单的多模态3D人体姿态估计算法,对比其他模型,该方法性能较好。最后总结了该数据集和该方法的限制。 …

沪尚茗居装修秘籍:嵌入式蒸烤箱,让厨房生活更精彩

在装修厨房时&#xff0c;选择一款合适的嵌入式蒸烤箱不仅能提升烹饪效率&#xff0c;还能为厨房增添一份现代感。沪尚茗居深知用户对厨房电器的需求&#xff0c;从实际出发&#xff0c;为用户推荐选购嵌入式蒸烤箱的实用技巧&#xff0c;让厨房生活更加美好。    首先&…

【千库网-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

leetcode二叉树(二)-二叉树的递归遍历

题目 . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出…

滑块验证码,给图就行

效果如上~ <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>滑块拼图验证码 - 拖动条 Loading 效…

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理

背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为&#xff0c;如连接&#xff0c;发送消息&#xff0c;认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能&#xff0c;但是目前emqx仅仅支持单个grpc服务端的设置&#xff0c;所以会有…

视频格式转换

格式转换 1️⃣Convertio &#x1f3c6;优点 速度快、格式多、免费免登录 缺点 超过100m的文件就要登录付费了 点击进入 2️⃣123APPs &#x1f3c6;优点 这个免费的文件上限是10G&#xff0c;完完全全够用功能多、除了转换器格式还有视频、音频、PDF处理工具 缺点 广…

无人机飞手执照培训,三类、四类傻傻分不清楚

无人机飞手执照培训中的三类和四类&#xff0c;主要依据无人机的空机重量进行区分&#xff0c;并对应不同的飞行权限和应用场景。以下是对这两类执照的详细解析&#xff1a; 一、无人机飞手执照的三类与四类定义 1. 三类执照&#xff1a; 定义&#xff1a;三类执照是指允许操…

架构设计笔记-9-软件可靠性

目录 知识要点 综合知识 案例分析 1.可靠性特性&#xff0c;软硬件可靠性对比 论文 1.论软件可靠性设计技术的应用 知识要点 软件架构需求过程主要是获取用户需求&#xff0c;标识系统中所要用到的构件&#xff0c;并进行架构需求评审。其中&#xff0c;标识构件又详细地…

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份&#xff1a;RDB触发机制rdb的触发时机&#xff1a;手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置&#xff0c;自动生成rdb快照RDB的优缺点 实时备份&#xff1a;AOFAOF是否会影响到red…

去耦电容的“滤波半径”

1、简介 去耦电容的滤波半径通常指的是在电路板上&#xff0c;去耦电容能够对其周围电源线路或信号线路产生有效去耦作用的范围。这个范围是以去耦电容为中心&#xff0c;向周围扩展的一个特定距离。 想象你有一个水桶&#xff0c;里面装满了混浊的水&#xff08;含有噪声的信…

基于ESP32的厨房计时器

基于ESP32的厨房计时器 一、项目说明二、项目材料三、OLED显示屏四、外壳设计五、外壳打印六、电路和外壳的集成七、编程八、成品展示 一、项目说明 厨房计时器很有用&#xff0c;但现在没有多少人使用实体厨房计时器了。我个人还是喜欢使用它们&#xff0c;因为拥有一个可以按…

CGAL 带约束的Delaunay三角剖分

CGAL 带约束的Delaunay三角剖分 本文使用CGAL进行简单的2D Delaunay 三角剖分,添加内外边界及点作为约束剖分。 Code #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Constrained_Delaunay_triangulation_2.h> #include <…

问题杂录-NVIDIA Bluefield DPU bfb-build编译报错记录与处理办法?(无数坑)

文章目录 背景bfb-build之后直接退出docker.io无法访问报错 ERROR: failed to solve: processkubernotes 下载失败报错mlnx-fw-updater-signed-24.07-0.6.1.1.aarch64: Cannot download报错 No match for argument: bf-release报错 放弃编译anolis&#xff0c;直接编译老版ubun…

RabbitMQ 入门(二)基本结构和消息模型

一、RabbitMQ的基本结构、角色和消息模型 MQ的基本结构&#xff1a; RabbitMQ中的一些角色&#xff1a; - publisher&#xff1a;生产者 - consumer&#xff1a;消费者 - exchange个&#xff1a;交换机&#xff0c;负责消息路由 - queue&#xff1a;队列&#xff0c;存储消息…