設計模式 - 抽象工廠

抽象工廠是對工廠的抽象化,而不只是制造方法。

為了滿足不同用戶對產品的多樣化需求,工廠不會只局限于生產一類產品,但是系統如果按工廠方法那樣為每種產品都增加一個工廠又會造成工廠泛濫。所以,為了調和這種矛盾,抽象工廠模式提供了另一種思路,將各種產品分門別類,基于此來規劃各種工廠的制造接口,最終確立產品制造的頂級規范。

一、品牌與系列

在工廠方法模式種每個實際的工廠直定義了一個工廠方法。而隨著經濟發展,人們對產品的需求不斷升級,并逐漸走向個性化、多元化,制造業隨之壯大起來。各類工廠遍地開發,能夠制造的產品種類也豐富了起來,隨之而來的弊端就是工廠泛濫。

針對這種情況,進行產業規劃與整合,對現有工廠進行重構。

  • 可以基于產品品牌與系列進行生產線規劃,按品牌分成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 切換為國內鏡像源工程化參考腳手架…