【设计模式-2.4】创建型——抽象工厂模式

说明:本文介绍设计模式中,创建型设计模式的抽象工厂设计模式;

工厂模式的问题

在【设计模式-2.2】创建型——简单工厂和工厂模式这篇博文中,介绍过飞机大战游戏里,使用简单工厂和工厂模式来创建坦克、飞机、Boss对象。

在这里插入图片描述

如果对象的类型过多,我们就需要创建更多的工厂类,并且如果我们需要对对象进行分类,如按照等级分类,坦克、飞机属于低等敌人,Boss属于高等敌人;按照战斗场景分类,坦克属于陆地,飞机属于天空,Boss可在陆地或者天空。

这就需要我们对现有的工厂类进一步抽取,抽象。

抽象工厂模式

在《秒懂设计模式》这本书中,提供了一种使用场景。如下:

在这里插入图片描述

作者假设某公司需要开发一款星际战争的游戏,游戏中兵种可分为人类与外星怪兽2个族,其中每个族又可分为1级、2级和3级,不同等级的兵种,攻击力、防御力和生命值不同;

(兵种接口)

/*** 兵种抽象类*/
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();
}

(低级兵种)

/*** 低级兵种*/
public abstract class LowClassUnit extends Unit{/*** 低级兵种* @param x* @param y*/public LowClassUnit(int x, int y) {super(5, 2, 35, x, y);}
}

(中级兵种)

/*** 中级兵种*/
public abstract class MidClassUnit extends Unit{/*** 中级兵种* @param x* @param y*/public MidClassUnit(int x, int y) {super(10, 8, 80, x, y);}
}

(高级兵种)

/*** 高级兵种*/
public abstract class HighClassUnit extends Unit{/*** 高级兵种* @param x* @param y*/public HighClassUnit(int x, int y) {super(25, 30, 300, x, y);}
}

(人族,低级兵种,海军陆战队)

/*** 海军陆战队*/
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);}
}

(人族,中级兵种,变形坦克)

/*** 变形坦克*/
public class Tank extends MidClassUnit{/*** 中级兵种** @param x* @param y*/public Tank(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("变形坦克出现了,坐标为:(" + x + "," + y + ")");}@Overridepublic void attack() {System.out.println("变形坦克攻击,攻击力为:" + attack);}
}

(人族,高级兵种,巨型战舰)

/*** 巨型战舰*/
public class Battleship extends HighClassUnit{/*** 高级兵种** @param x* @param y*/public Battleship(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("巨型战舰出现了,坐标为:(" + x + "," + y + ")");}@Overridepublic void attack() {System.out.println("巨型战舰攻击,攻击力为:" + attack);}
}

(怪兽族,低级兵种,螳螂)

/*** 螳螂*/
public class Roach extends LowClassUnit{/*** 低级兵种** @param x* @param y*/public Roach(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("螳螂出现了,坐标为:(" + x + "," + y + ")");}@Overridepublic void attack() {System.out.println("螳螂攻击,攻击力为:" + attack);}
}

(怪兽组,中级兵种,毒液)

/*** 毒液*/
public class Poison extends MidClassUnit {/*** 中级兵种** @param x* @param y*/public Poison(int x, int y) {super(x, y);}@Overridepublic void show() {System.out.println("毒液出现了,坐标为:(" + x + "," + y + ")");}@Overridepublic void attack() {System.out.println("毒液攻击,攻击力为:" + attack);}
}

(怪兽组,高级兵种,猛犸)

/*** 猛犸*/
public class Mammoth extends HighClassUnit {/*** 高级兵种** @param x* @param y*/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个工厂类,且这些工厂类互相没有联系,因此我们考虑使用抽象工厂模式,如下:

(抽象兵种工厂)

/*** 抽象兵种工厂*/
public interface AbstractFactory {/*** 创建低级兵种* @return*/LowClassUnit createLowClassUnit();/*** 创建中级兵种* @return*/MidClassUnit createMidClassUnit();/*** 创建高级兵种* @return*/HighClassUnit createHighClassUnit();
}

(人类兵种工厂)

/*** 人类兵种工厂*/
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 createLowClassUnit() {LowClassUnit unit = new Marine(x, y);System.out.println("制造海军陆战队员成功。");return unit;}@Overridepublic MidClassUnit createMidClassUnit() {MidClassUnit unit = new Tank(x, y);System.out.println("制造变形坦克成功。");return unit;}@Overridepublic HighClassUnit createHighClassUnit() {HighClassUnit unit = new Battleship(x, y);System.out.println("制造巨型战舰成功。");return unit;}
}

(外星怪兽兵种工厂)

/*** 外星人兵种工厂*/
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 createLowClassUnit() {LowClassUnit unit = new Roach(x, y);System.out.println("制造蟑螂成功。");return unit;}@Overridepublic MidClassUnit createMidClassUnit() {MidClassUnit unit = new Poison(x, y);System.out.println("制造毒液成功。");return unit;}@Overridepublic HighClassUnit createHighClassUnit() {HighClassUnit unit = new Mammoth(x, y);System.out.println("制造猛犸象成功。");return unit;}
}

(客户端,演示人类兵种、怪兽兵种的创建)

/*** 客户端*/
public class Client {public static void main(String[] args) {System.out.println("......人类兵种工厂开始制造兵种......");// 创建人类兵种工厂AbstractFactory humanFactory = new HumanFactory(10, 10);// 创建低级兵种LowClassUnit humanLowClassUnit = humanFactory.createLowClassUnit();// 创建中级兵种MidClassUnit humanMidClassUnit = humanFactory.createMidClassUnit();// 创建高级兵种HighClassUnit humanHighClassUnit = humanFactory.createHighClassUnit();// 低级兵种展示和攻击humanLowClassUnit.show();humanLowClassUnit.attack();// 中级兵种展示和攻击humanMidClassUnit.show();humanMidClassUnit.attack();// 高级兵种展示和攻击humanHighClassUnit.show();humanHighClassUnit.attack();System.out.println("==========================================================");System.out.println("......外星人兵种工厂开始制造兵种......");// 创建外星人兵种工厂AbstractFactory alienFactory = new AlienFactory(200, 200);// 创建低级兵种LowClassUnit alienLowClassUnit = alienFactory.createLowClassUnit();// 创建中级兵种MidClassUnit alienMidClassUnit = alienFactory.createMidClassUnit();// 创建高级兵种HighClassUnit alienHighClassUnit = alienFactory.createHighClassUnit();// 低级兵种展示和攻击alienLowClassUnit.show();alienLowClassUnit.attack();// 中级兵种展示和攻击alienMidClassUnit.show();alienMidClassUnit.attack();// 高级兵种展示和攻击alienHighClassUnit.show();alienHighClassUnit.attack();}
}

以上是抽象工厂模式创建对象的过程。抽象工厂模式是对工厂模式的一种提炼,当我们需要对系统中的对象进行分类区别时,应当考虑使用抽象工厂模式。

总结

本文参考《设计模式的艺术》、《秒懂设计模式》两书,代码来自《秒懂设计模式》,略有不同。

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

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

相关文章

【极客公园 IF 2024】用AI 增强自己的人生

周末去了 极客公园组织的创新大会2024 原文链接:《刘擎对话叶军|当疑虑的人文学者向乐观的创业者发问:我们如何理解 AI 时代?》 人文学者刘擎老师的观点很吸引人 AI 技术突破改变生活,没有人比自己更了解你自己&…

如何集成和使用Feign的远程调用

feign的简单介绍 Feign是一个声明式的http客户端,可以帮助我们优雅的实现http请求的发送 OpenFeign/feign: Feign makes writing java http clients easier (github.com)Spring Cloud OpenFeign 中文文档 (springdoc.cn)Spring Cloud OpenFeign在spring cloud的基础…

DevEco Studio 项目鸿蒙(HarmonyOS)多语言

DevEco Studio 项目鸿蒙(HarmonyOS)多语言 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、多语言 新版本IDE可以创建多语言的文件夹,在entry->src->main->resources下,修…

初级数据结构(六)——堆

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;五&#xff09;——树和二叉树的概念 | NULL 下一篇-> 1、堆的特性 1.1、定义 堆结构属于完全二叉树的范畴&#xff0c;除了满足完全二叉树的限制之外&#xff0c;还满…

【LeetCode刷题-字符串】-- 186.反转字符串中的单词II

186.反转字符串中的单词II 方法&#xff1a;先反转整个字符串再反转单词中的字母 class Solution {public void reverseWords(char[] s) {reverseCharacters(s,0,s.length-1);reverseEachWord(s);}//反转单词中的字母public void reverseEachWord(char[] s){int length s.len…

Mybatis Plus

一、MyBatis-Plus 1.简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 我们的愿景是成为 MyBatis 最好的搭档&…

centOS7 安装tailscale并启用子网路由

1、在centOS7上安装Tailscale客户端 #安装命令所在官网位置&#xff1a;https://tailscale.com/download/linux #具体命令为&#xff1a; curl -fsSL https://tailscale.com/install.sh | sh #命令执行后如下图所示2、设置允许IP转发和IP伪装。 安装后&#xff0c;您可以启动…

力扣刷题-二叉树-二叉树的所有路径

257 二叉树的所有路径 给定一个二叉树&#xff0c;返回所有从根节点到叶子节点的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 思路 参考&#xff1a; https://www.programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE…

10天玩转Python第8天:python 文件和异常 全面详解与代码示例

今日内容 文件操作 普通文件的操作json 文件的操作[重点] 异常处理(程序代码运行时的报错) 文件介绍 计算机的 文件&#xff0c;就是存储在某种 长期储存设备 上的一段 数据 作用: 将数据长期保存下来&#xff0c;在需要的时候使用 ​ 1.计算机只认识 二进制(0 1) 2.文件中…

广受好评的开源基础大模型最全梳理,你最钟意哪一个?

2023 年即将过去。一年以来&#xff0c;各式各样的大模型争相发布。当 OpenAI 和谷歌等科技巨头正在角逐时&#xff0c;另一方「势力」悄然崛起 —— 开源。 开源模型受到的质疑一向不少。它们是否能像专有模型一样优秀&#xff1f;是否能够媲美专有模型的性能&#xff1f; 迄…

jrebel debug 启动不起来

idea更新之后jrebel debug模式启动不起来。 将下面的设置取消之后就可以了&#xff0c;希望能帮到你们… 被卡了两天… jrebel信息。 idea IntelliJ IDEA 2023.3.1 (Ultimate Edition) Build #IU-233.11799.300, built on December 12, 2023 Licensed to Alexandra Martin…

【SpringBoot零基础入门到项目实战②】安装Java和Maven,创建你的第一个项目

文章目录 导言安装JavaWindows系统macOS系统Linux系统 安装和配置 MavenWindows系统macOS系统Linux系统配置 Maven 本地仓库使用阿里镜像加速 创建第一个Spring Boot项目拓展学习&#xff08;提前了解 后面会讲到&#xff09;1. 深入理解Spring Boot的项目结构2. 学习Spring Bo…