抽象工厂是对工厂的抽象化,而不只是制造方法。

为了满足不同用户对产品的多样化需求,工厂不会只局限于生产一类产品,但是系统如果按工厂方法那样为每种产品都增加一个工厂又会造成工厂泛滥。所以,为了调和这种矛盾,抽象工厂模式提供了另一种思路,将各种产品分门别类,基于此来规划各种工厂的制造接口,最终确立产品制造的顶级规范。

一、品牌与系列

在工厂方法模式种每个实际的工厂直定义了一个工厂方法。而随着经济发展,人们对产品的需求不断升级,并逐渐走向个性化、多元化,制造业随之壮大起来。各类工厂遍地开发,能够制造的产品种类也丰富了起来,随之而来的弊端就是工厂泛滥。

针对这种情况,进行产业规划与整合,对现有工厂进行重构。

  • 可以基于产品品牌与系列进行生产线规划,按品牌分成A工厂与B工厂
  • 基于这两个品牌汽车工厂的系列生产线,如果今后产生新的C品牌汽车、D品牌汽车等,都可以沿用此种规划好的生产模式,这便是抽象工厂模式的基础数据模型。


二、产品规划

无论哪种工厂模式,都一定是基于特定的产品特性发展而来的。假如公司要开发一款星际战争游戏,战争设定在太阳系文明与外星文明之间展开,游戏兵种就可以分为人类和外星怪兽两个族。

 人类有各种军工高科技装备、外星靠血肉之躯与人类战斗。所以将兵种按照族进行划分。

兵种规划表格以列划分等级,以行划分族,一目了然,我们可以根据这个建立数据模型。

首先,我们来定义一个所有兵种的顶级父类兵种,这里我们使用抽象类,以达到属性继承给子类的目的。

public abstract class Unit {protected int attack; // 攻击力protected int defence; // 防御力protected int health; // 生命力protected int x; // 横坐标protected int y; // 纵坐标public Unit(int attack, int defence, int health, int x, int y) {this.attack = attack;this.defence = defence;this.health = health;this.x = x;this.y = y;}public abstract void show();public abstract void attack();
}

任何兵种都有攻击力、防御力、生命力、坐标方位等属性。

接下来我们将兵种按等级分类,假设同一等级的攻击力、防御力等属性值是相同的,所以初级、中级、高级兵种会分别对应三个等级的兵种类:

1. 初级兵种类 LowClassUnit

public abstract class LowClassUnit extends Unit {public LowClassUnit(int x, int y) {super(5, 2, 35, x, y);}
}

2. 中级兵种类 MidClassUnit

public abstract class MidClassUnit extends Unit {public MidClassUnit(int x, int y) {super(10, 8, 80, x, y);}
}

3. 高级兵种类 HighClassUnit

public abstract class HighClassUnit extends Unit {public HighClassUnit(int x, int y) {super(25, 30, 300, x, y);}
}

各等级兵种类都继承自兵种抽象类Unit,接下来定义具体的兵种类:

1. 海军陆战队员类 Marine

public class Marine extends LowClassUnit {public Marine(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("士兵出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("士兵用机关枪射击,攻击力: " + attack);}
}

2. 变形坦克类 Tank

public class Tank extends MidClassUnit {public Tank(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("坦克出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("坦克用炮轰击,攻击力: " + attack);}
}

3. 巨型战舰类 Battleship

public class Battleship extends HighClassUnit {public Battleship(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("战舰出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("战舰用激光炮打击,攻击力: " + attack);}
}

如图,我们构造方法中调用了父类,并初始化了坐标属性,其攻击力、防御力和生命力已经在对应等级的父类里面初始化好了。

1. 蟑螂类 Roach

public class Roach extends LowClassUnit {public Roach(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("蟑螂兵出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("蟑螂兵用爪子挠,攻击力: " + attack);}
}

2. 毒液类 Poison

public class Poison extends MidClassUnit {public Poison(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("毒液兵出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("毒液兵用毒液喷射,攻击力: " + attack);}
}

3. 猛犸类 Mammoth

public class Mammoth extends HighClassUnit {public Mammoth(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("猛犸巨兽出现在坐标: [" + x + "," + y + "]");}@Overridepublic void attack() {System.out.println("猛犸巨兽用獠牙顶,攻击力: " + attack);}
}

至此,所有兵种类已经定义完毕,代码不是难点,重点集中在对兵种的划分上,横向划分族、纵向划分等级,利用类的抽象与继承描绘出所有的游戏角色以及他们之间的关系,同时避免了不少重复代码。


三、生产线规划

既然产品类的数据模型构建完成,相应的产品线也应该建立起来,接下来就定义这些产品的制造工厂。我们一共定义了6个兵种产品,那么每个产品都要对应一个工厂类吗?答案是否定的。

人类兵工厂是高度工具化的、怪兽靠母巢繁殖,所以应该将工厂分为两个族,并且每个族工厂有3个等级兵种的制造方法。

如此规划不但合理,而且避免了工厂类泛滥的问题。

1. 抽象兵工厂接口定义了三个等级兵种的制造标准

意味着子类工厂必须具备初级、中级、高级兵种的生产能力。

public interface AbstractFactory {LowClassUnit createLowClass(); // 初级兵种制造标准MidClassUnit createMidClass(); // 中级兵种制造标准HighClassUnit createHighClass(); // 高级兵种制造标准
}

2. HumanFactory 类

public class HumanFactory implements AbstractFactory {private int x; // 工厂横坐标private int y; // 工厂纵坐标public HumanFactory(int x, int y) {this.x = x;this.y = y;}@Overridepublic LowClassUnit createLowClass() {LowClassUnit unit = new Marine(x, y);System.out.println("制造海军陆战队员成功.");return unit;}@Overridepublic MidClassUnit createMidClass() {MidClassUnit unit = new Tank(x, y);System.out.println("制造变形坦克成功.");return unit;}@Overridepublic HighClassUnit createHighClass() {HighClassUnit unit = new Battleship(x, y);System.out.println("制造巨型战舰成功.");return unit;}
}

2. AlienFactory 类

public class AlienFactory implements AbstractFactory {private int x; // 工厂横坐标private int y; // 工厂纵坐标public AlienFactory(int x, int y) {this.x = x;this.y = y;}@Overridepublic LowClassUnit createLowClass() {LowClassUnit unit = new Roach(x, y);System.out.println("制造蟑螂兵成功.");return unit;}@Overridepublic MidClassUnit createMidClass() {MidClassUnit unit = new Poison(x, y);System.out.println("制造毒液兵成功.");return unit;}@Overridepublic HighClassUnit createHighClass() {HighClassUnit unit = new Mammoth(x, y);System.out.println("制造猛犸巨兽成功.");return unit;}
}

人类兵工厂与外星母巢分别实现了三个等级兵种的制造方法,其中前者由低到高分别返回海军陆战队员、变形坦克以及巨型战舰对象,后者则分别返回蟑螂兵、毒液兵以及猛犸兽对象,生产线规划非常清晰。

客户端调用

public class Client {public static void main(String[] args) {System.out.println("游戏开始……");System.out.println("双方挖矿攒钱……");// 第一位玩家选择了人类族System.out.println("工人建造人类族工厂……");AbstractFactory factory = new HumanFactory(10, 10);Unit marine = factory.createLowClass();marine.show();Unit tank = factory.createMidClass();tank.show();Unit ship = factory.createHighClass();ship.show();// 第二位玩家选择了外星怪兽族System.out.println("工蜂建造外星怪兽族工厂……");factory = new AlienFactory(200, 200);Unit roach = factory.createLowClass();roach.show();Unit poison = factory.createMidClass();poison.show();Unit mammoth = factory.createHighClass();mammoth.show();System.out.println("两族开始大混战……");marine.attack();roach.attack();poison.attack();tank.attack();mammoth.attack();ship.attack();}
}

至此,抽象工厂制造模式已经布局完成。

产品虽然繁多,但总有品牌、系列之分。基于此抽象工厂模式以品牌与系列进行全局规划,将看似杂乱无章的产品规划到不同的族系,再通过抽象工厂管理起来,分而治之,合纵连横。

需要注意的是,抽象工厂模式一定是基于产品的族系来划分布局的,其产品邪猎一定是相对固定的,固以抽象工厂来确立工业制造标准。而产品族则可以相对灵活多变,如此一来,我们就可以方便的扩展与替换族工厂,以达到灵活产出各类产品族系的目的。

-- 秒懂设计模式学习笔记

-- 抽象工厂

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

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

相关文章

面向对象Plus(2/2)

目录 面向对象Plus(qianwen) 一.面向对象三大特性 封装 继承 多态 二.多态 1.了解多态 2.体验多态 三.类属性和实例属性 1.类属性 a.设置和访问类属性 类属性的优点 b.修改类属性 四.类方法和静态方法 1.类方法 a.类方法特点 b.类方法应用场景 2.静态方法 a…

MocapApi 中文文档 和github下载地址 NeuronDataReader(以下简称 NDR)的下一代编程接口

以下是 MocapApi 技术文档 github https://github.com/pnmocap/MocapApi?tabreadme-ov-file 国内可以查找getcode 英文文档 https://mocap-api.noitom.com/mocap_api_en.html 概述 MocapApi 是 NeuronDataReader(以下简称 NDR)的下一代编程接口&…

STM32历史、命名、Flash、工作频率

目录 命名: Flash: 工作频率: 复位: 低功耗模式: IO端口: JATG: 看门狗定时器: STM是一家半导体公式,专门做芯片的,STM32是指32位的微处理器,其中芯片的架构是ARM结构的&#…

了解公共部门中的数据网格:支柱、架构和示例

作者:来自 Elastic Elastic Platform Team 想想那些像公共健康记录、城市规划模型等项目背后的所有数据。政府机构一直在产生大量数据。当数据分散在云平台、本地系统或像卫星和应急响应中心这样的专业环境中时,情况变得更加复杂。找到信息变得困难&…

阿里云ACP-检索分析服务

当数据量爆炸增长,并且需要提供全文检索功能,需要有效的数据检索能力 用什么数据库怎么保证安全性如何解决统计分析问题如何解决单点故障如何解决检索难题 应对方案: 关系型数据库:主从备份解决数据安全性问题,数据…

【DBeaver】跨平台数据库连接工具DBeaver Community 23.2.5安装配置使用

DBeaver是一款免费开源的通用数据库管理工具和SQL客户端,支持多种数据库系统。它基于Java开发,具备跨平台能力,可以在Windows、macOS和Linux系统上运行。 目录 安装DBeaver 连接MySQL数据库 安装DBeaver 进入DBeaver官网 DBeaver Communit…

【钱包】WEB3钱包APP框架的设计

【钱包】WEB3钱包APP框架的设计 一、前言 前段时间,自己做了一款WEB3钱包APP,从产品设计到框架搭建都是我一个人搞的,更多的参考了其他公司的钱包APP。 在此,想把自己的钱包经验分享出来,帮助没有做过钱包APP的同学开…

openGL学习(基本窗口)

学习路线 学习 OpenGL 需要掌握一系列基础知识和技能,这些内容涵盖了计算机图形学的基本概念、编程语言、数学知识以及 OpenGL 的具体 API 使用。以下是学习 OpenGL 所需的主要知识点: 1. 计算机图形学基础 图形学概念:了解图形学的基本概…

无人机防护装置技术解析

一、技术要点 1. 侦测防御系统 多频谱复合探测 整合无线电侦测(20MHz–6GHz频段扫描)、雷达探测、光电跟踪(可见光/红外/激光)技术,实现360无死角监测。例如神州明达系统可5公里内识别无人机信号,并同步…

2.2.2、CAN总线-测试模式、工作模式

目录 1、测试模式 2、工作模式 (1) (2)SLEEP位: (3)INRQ位:(Init Request) (4)ACK:应答 (5)…

区块链大讲堂 | 分布式隐私计算友好的零知识证明协议

区块链大讲堂 主讲人:上海交通大学计算机学院助理教授胡云聪 报告题目:分布式隐私计算友好的零知识证明协议 参与方式:扫描海报二维码报名参与活动

MyBatis映射文件(XML)中参数传递和SQL特殊字符处理

1. 参数占位符 1.1 #{} 和 ${} 的区别 #{} 占位符 作用:安全传参。MyBatis在执行SQL时,会把#{}替换成?,然后用参数值自动填充。 优点:可以防止SQL注入,推荐使用。 例子: select * from user wher…

C语言 数据结构 --排序 (直接插入排序,选择排序,交换排序......)

引言:本章简洁的讲解一下数据结构中的几个常见的排序 ,作复习之用,后面可能会补一些其他的排序 。并给出一些小编学习中遇到的坑,作借鉴。 1.直接插入排序 直接插入排序是一种简单直观的排序算法,其基本思想是将一个数…

华为云发布盘古大模型 5.5 新一代昇腾 AI 云服务上线

2025 年 6 月 20 日,华为开发者大会 2025(HDC 2025)在东莞召开。华为常务董事、云计算 CEO 张平安宣布基于 CloudMatrix 384 超节点的新一代昇腾 AI 云服务全面上线,并发布盘古大模型 5.5,五大基础模型实现技术突破&am…

Reactor Handle

handle 是 Reactor 中一个非常灵活的操作符,它允许你对每个源元素进行处理,并可以选择性地发出零个或多个元素。它既可以用于映射(map)也可以用于过滤(filter),因此可以看作是 map 和 filter 的…

C#哈希加密:原理、实现与应用

C#哈希加密:原理、实现与应用 在当今数字化时代,数据安全是每个应用程序都必须重视的问题。哈希加密作为一种重要的加密技术,在密码存储、数据完整性验证、数字签名等领域发挥着关键作用。本文将深入探讨C#中哈希加密的原理、常用算法以及实…

httpbin.org是什么,有什么作用

httpbin.org 是一个开源的 HTTP 请求与响应测试服务,基于 Python 的 Flask 框架开发 它允许开发者发送各种 HTTP 请求,并返回请求的详细信息,便于调试和验证 HTTP 客户端的行为。以下是其核心功能和作用详解: 一、核心功能与作用…

mongodb生产备份工具PBM

如果你的 MongoDB 数据量特别大(例如几十 GB、TB 级别),普通的 mongodump/mongorestore 会显得缓慢且资源消耗大,不适合生产级别大数据集。下面是当前 MongoDB 社区和企业广泛使用的几种备份方案对比和推荐: 工具是否…

【LeetCode#第167题】两数之和Ⅱ

给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index2 < numbers…

Python(一)实现一个爬取微信小程序数据的爬虫+工程化初步实践

文章目录 前言用Charles 抓包 iOS 微信小程序在Mac端和iOS端安装Charles 自签名证书Mac端iOS端 能抓到Safari浏览器的包但是抓不到微信小程序的包直接在iOS 上抓包的App如何抓取Android 7.0 以上/Harmony OS微信小程序包 Python 项目工程化pip 切换为国内镜像源工程化参考脚手架…