秒懂設計模式--學習筆記(5)【創建篇-抽象工廠】

目錄

      • 4、抽象工廠
          • 4.1 介紹
          • 4.2 品牌與系列(針對工廠泛濫)(**分類**)
          • 4.3 產品規劃(**數據模型**)
          • 4.4 生產線規劃(**工廠類**)
          • 4.5 分而治之
          • 4.6 抽象工廠模式的各角色定義如下
          • 4.7 基于此抽象工廠模式以品牌與系列進行全局規劃

4、抽象工廠

4.1 介紹
  • 抽象工廠模式(Abstract Factory)是對工廠的抽象化,而不只是制造方法
  • 系統如果按工廠方法那樣為每種產品都增加一個新工廠又會造成工廠泛濫
  • 抽象工廠模式提供了另一種思路,將各種產品分門別類
  • 基于此來規劃各種工廠的制造接口,最終確立產品制造的頂級規范,使其與具體產品徹底脫鉤
  • 抽象工廠是建立在制造復雜產品體系需求基礎之上的一種設計模式
  • 在某種意義上,我們可以將抽象工廠模式理解為工廠方法模式的高度集群化升級版
  • 測試類文件
    測試類文件結構
4.2 品牌與系列(針對工廠泛濫)(分類)
  • 產品多元化 --> 工廠泛濫 --> 產業規劃與整合
    • A品牌3系列 + B品牌3系列 + …
    • 這便是抽象工廠模式的基礎數據模型
    • 分為品牌工廠,系列工廠
4.3 產品規劃(數據模型
  • 無論哪種工廠模式,都一定是基于特定的產品特性發展而來的: 從產品建模切入(提取相同點,找出不同點)
  • 例子(星際戰爭游戲)
  • 分析規劃(提取相同點,找出不同點)
    • 兵種:人族、怪獸族…
    • 等級:1及、2級、3級…
  • 建立數據模型
  • 兵種頂層父類
package abstractFactory.entity.abstractt;/*** 兵種抽象類**/
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();
}
  • 兵種等級: 各等級兵種類都繼承自兵種抽象類Unit,它們對應的攻擊力、防御力及生命力也各不相同
    • 初級兵種類LowClassUnit
    • 中級兵種類MidClassUnit
    • 高級兵種類HighClassUnit
package abstractFactory.entity.abstractt;
/*** 初級兵種類**/
public abstract class LowClassUnit extends Unit{public LowClassUnit( int x, int y) {super(5, 2, 35, x, y);}
}
package abstractFactory.entity.abstractt;
/*** 中級兵種類**/
public abstract class MidClassUnit extends Unit {public MidClassUnit( int x, int y) {super(10, 8, 80, x, y);}
}
package abstractFactory.entity.abstractt;
/*** 高級兵種類**/
public abstract class HighClassUnit extends Unit {public HighClassUnit( int x, int y) {super(25, 30, 300, x, y);}
}
  • 定義具體的兵種類
    • 海軍陸戰隊員類Marine
    • 變形坦克類Tank
    • 巨型戰艦類Battleship
    • 蟑螂類Roach
    • 毒液類Poison
    • 猛犸類Mammoth
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
/*** 海軍陸戰隊員類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);}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
/*** 變形坦克類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);}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
/*** 巨型戰艦類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);}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.LowClassUnit;
/*** 蟑螂類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);}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.MidClassUnit;
/*** 毒液類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);}
}
package abstractFactory.entity.product;
import abstractFactory.entity.abstractt.HighClassUnit;
/*** 猛犸類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);}
}
  • 所有兵種類已定義完畢,代碼不是難點,重點集中在對兵種的劃分上
  • 橫向劃分族,縱向劃分等級(系列),利用類的抽象與繼承描繪出所有的游戲角色以及它們之間的關系,同時避免了不少重復代碼
4.4 生產線規劃(工廠類
  • 數據模型構建完成,定義工廠,建立生產線
    • 定義了6個兵種產品(數據模型):實體
    • 可分為2個工廠:人族、怪獸族
    • 3個制造標準:3個等級
  • 定義抽象工廠接口:
    • 3個制造標準方法
package abstractFactory.factory;import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;/*** 定義抽象工廠接口 : 抽象兵工廠接口*      抽象兵工廠接口定義了3個等級兵種的制造標準, 這意味著子類工廠必須具備初級、中級、高級兵種的生產能力**/
public interface AbstractFactory {/*** 初級兵種制造標準* @return*/LowClassUnit createLowClassUnit();/*** 中級兵種制造標準* @return*/MidClassUnit createMidClassUnit();/*** 高級兵種制造標準* @return*/HighClassUnit createHighClassUnit();
}
  • 工廠類實現
package abstractFactory.factory.impl;import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Battleship;
import abstractFactory.entity.product.Marine;
import abstractFactory.entity.product.Tank;
import abstractFactory.factory.AbstractFactory;
/*** 人類兵工廠**/
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;}
}
package abstractFactory.factory.impl;import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.product.Mammoth;
import abstractFactory.entity.product.Poison;
import abstractFactory.entity.product.Roach;
import abstractFactory.factory.AbstractFactory;/*** 外星母巢(工廠)**/
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 roach = new Roach(x, y);System.out.println("制造蟑螂兵成功。");return roach;}@Overridepublic MidClassUnit createMidClassUnit() {MidClassUnit poison = new Poison(x, y);System.out.println("制造毒液兵成功。");return poison;}@Overridepublic HighClassUnit createHighClassUnit() {HighClassUnit mammoth = new Mammoth(x, y);System.out.println("制造猛犸巨獸成功。");return mammoth;}
}
  • 生產線規劃非常清晰
    • 人類兵工廠與外星母巢分別實現了3個等級兵種的制造方法
    • 其中前者由低到高分別返回海軍陸戰隊員、變形坦克以及巨型戰艦對象,
    • 后者則分別返回蟑螂兵、毒液兵以及猛犸巨獸對象
  • 測試使用
    • 抽象兵工廠接口引用了人類兵工廠實現
    • 調用3個等級的制造方法分別得到人類族的對應兵種
    • 將抽象兵工廠接口引用替換為外星母巢實現
    • 制造出的兵種變為3個等級的外星怪獸族兵種
    • 如果玩家需要一個新族加入,我們可以在此模式之上去實現一個新的族工廠并實現3個等級的制造方法
    • 工廠一經替換即可產出各系列產品兵種,且無須改動現有代碼,良好的可擴展性
    • 這就是一套擁有完備生產模式的標準化工業系統所帶來的好處
package abstractFactory;import abstractFactory.entity.abstractt.HighClassUnit;
import abstractFactory.entity.abstractt.LowClassUnit;
import abstractFactory.entity.abstractt.MidClassUnit;
import abstractFactory.entity.abstractt.Unit;
import abstractFactory.factory.AbstractFactory;
import abstractFactory.factory.impl.AlienFactory;
import abstractFactory.factory.impl.HumanFactory;
/*** 測試客戶端類**/
public class Client {/***  打印結果*      游戲開始......*      雙方挖掘攢錢......*      建造人類族工廠.......*      制造海軍陸戰隊員成功。*      士兵出現在坐標:[10,10]*      制造變形坦克成功。*      坦克出現在坐標:[10,10]*      制造巨型戰艦成功。*      戰艦出現在坐標:[10,10]*      建造外星怪獸族工廠*      制造蟑螂兵成功。*      蟑螂兵出現在坐標:[200,200]*      制造毒液兵成功。*      毒液兵出現在坐標:[200,200]*      制造猛犸巨獸成功。*      猛犸巨獸出現在坐標:[200,200]*      兩族開始混戰......*      士兵用機關槍射擊,攻擊力:5*      蟑螂兵用爪子撓,攻擊力:5*      毒液兵用毒液噴射,攻擊力:10*      坦克用炮轟擊,攻擊力:10*      猛犸巨獸用獠牙頂,攻擊力:25*      戰艦用激光炮打擊,攻擊力:25* @param args*/public static void main(String[] args) {System.out.println("游戲開始......");System.out.println("雙方挖掘攢錢......");// 第一位玩家選擇了人類族System.out.println("建造人類族工廠.......");// 抽象兵工廠接口引用了人類兵工廠實現AbstractFactory factory = new HumanFactory(10, 10);Unit marine = factory.createLowClassUnit();marine.show();Unit tank = factory.createMidClassUnit();tank.show();Unit ship = factory.createHighClassUnit();ship.show();// 第二位萬家選擇了外星怪獸族System.out.println("建造外星怪獸族工廠");/*** 抽象兵工廠接口引用替換為外星母巢實現* 工廠一經替換即可產出各系列產品兵種,且無須改動現有代碼,良好的可擴展性*/factory = new AlienFactory(200, 200);Unit roach = factory.createLowClassUnit();roach.show();Unit poison = factory.createMidClassUnit();poison.show();Unit mammoth = factory.createHighClassUnit();mammoth.show();System.out.println("兩族開始混戰......");marine.attack();roach.attack();poison.attack();tank.attack();mammoth.attack();ship.attack();}
}
4.5 分而治之
  • 抽象工廠制造模式已經布局完成,各工廠可以隨時大規模投入生產活動了
  • 我們還可以進一步,再加一個“制造工廠的工廠”來決定具體讓哪個工廠投入生產活動
  • 此時客戶端就無須關心工廠的實例化過程了,直接使用產品就可以了
  • 這也是抽象工廠可以被視為“工廠的工廠”的原因
  • 與工廠方法模式不同,抽象工廠模式能夠應對更加復雜的產品族系,它更類似于一種對“工業制造標準”的制定與推行
    • 各工廠實現都遵循此標準來進行生產活動
    • 工廠類劃分產品族(工廠類)
    • 制造方法劃分產品系列(數據模型)
    • 達到無限擴展產品的目的
4.6 抽象工廠模式的各角色定義如下
  • 產品系列的抽象類:
    • AbstractProduct1、AbstractProduct2(抽象產品1、抽象產品2)
    • 一系產品與二系產品分別代表同一產品族多個產品系列,對應本章例程中的初級、中級、高級兵種抽象類
  • 繼承自抽象產品的產品實體類(數據模型)
    • ProductA1、ProductB1、ProductA2、ProductB2(產品A1、產品B1、產品A2、產品B2)
    • 其中ProductA1與ProductB1代表A族產品與B族產品的同一產品系列,類似于例中人類族與外星怪獸族的初級兵種
  • 抽象工廠接口(AbstractFactory)
    • 各族工廠的高層抽象,可以是接口或者抽象類
    • 抽象工廠對各產品系列的制造標準進行規范化定義,但具體返回哪個族的產品由具體族工廠決定,它并不關心。
  • 工廠實現類:
    • ConcreteFactoryA、ConcreteFactoryB(工廠A實現、工廠B實現)
    • 繼承自抽象工廠的各族工廠,需實現抽象工廠所定義的產品系列制方法,可以擴展多個工廠實現。
    • 對應本章例程中的人類兵工廠與外星母巢
  • Client(客戶端):
    • 產品的使用者,只關心制造出的產品系列,具體是哪個產品族由工廠決定
4.7 基于此抽象工廠模式以品牌與系列進行全局規劃
  • 抽象工廠模式一定是基于產品的族系劃分來布局的
  • 產品系列一定是相對固定的
  • 故以抽象工廠來確立工業制造標準(各產品系列生產接口)
  • 而產品族則可以相對靈活多變

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/39093.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39093.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39093.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue啟動時的錯誤

解決辦法一:在vue.config.js中直接添加一行代碼 lintOnSave:false 關閉該項目重新運行就可啟動 解決辦法二: 修改組件名稱

Python容器 之 通用功能

1.切片 1.格式: 數據[起始索引:結束索引:步長 2.適用類型: 字符串(str)、列表(list)、元組(tuple) 3.說明: 通過切片操作, 可以獲取數據中指定部分的內容 4.注意 : 結束索引對應的數據不會被截取到 支持正向索引和逆向索引 步長用于設置截取…

配音軟件有哪些?分享五款超級好用的配音軟件

隨著嫦娥六號的壯麗回歸,舉國上下都沉浸在這份自豪與激動之中。 在這樣一個歷史性的時刻,我們何不用聲音記錄下這份情感,讓這份記憶以聲音的形式流傳? 無論是制作視頻分享這份喜悅,還是創作音頻講述探月故事&#xff…

Oracle數據庫中RETURNING子句

RETURNING子句允許您檢索插入、刪除或更新所修改的列(以及基于列的表達式)的值。如果不使用RETURNING,則必須在DML語句完成后運行SELECT語句,才能獲得更改列的值。因此,RETURNING有助于避免再次往返數據庫,…

Plotly:原理、使用與數據可視化的未來

文章目錄 引言Plotly的原理Plotly的基本使用安裝Plotly創建基本圖表定制圖表樣式 Plotly的高級特性交互式圖表圖表動畫圖表集成 結論 引言 在當今的數據驅動世界中,數據可視化已經成為了一個至關重要的工具。它允許我們直觀地理解數據,發現數據中的模式…

CXL-GPU: 全球首款實現百ns以內的低延遲CXL解決方案

數據中心在追求更高性能和更低總擁有成本(TCO)的過程中面臨三大主要內存挑戰。首先,當前服務器內存層次結構存在局限性。直接連接的DRAM與固態硬盤(SSD)存儲之間存在三個數量級的延遲差異。當處理器直接連接的內存容量…

VideoPrism——探索視頻分析領域模型的算法與應用

概述 論文地址:https://arxiv.org/pdf/2402.13217.pdf 視頻是我們觀察世界的生動窗口,記錄了從日常瞬間到科學探索的各種體驗。在這個數字時代,視頻基礎模型(ViFM)有可能分析如此海量的信息并提取新的見解。迄今為止,…

【vuejs】vue-router 路由跳轉參數傳遞詳解和應用場景及技巧

1. Vue2 Router 路由基礎 1.1 路由定義 路由定義是Vue Router中實現頁面路由跳轉的基礎。在Vue2中,路由的定義通常在應用的入口文件或路由配置文件中進行。路由定義涉及到路徑模式(path)、視圖組件(component)以及一…

【數據分析思維--史上最全最牛逼】

前言: 💞💞大家好,我是書生?,主要和大家分享一下數據分析的思維!怎么提好我們對于業務的判斷是非常重要的!!!希望對大家有所幫助。 💞💞代碼是你…

采煤機作業3D虛擬仿真教學線上展示增強應急培訓效果

在化工行業的生產現場,安全永遠是首要之務。為了加強從業人員的應急響應能力和危機管理能力,紛紛引入化工行業工藝VR模擬培訓,讓應急演練更加生動、高效。 化工行業工藝VR模擬培訓軟件基于真實的廠區環境,精確還原了各類事件場景和…

醫療器械FDA | 醫療器械軟件如何做源代碼審計?

醫療器械網絡安全測試https://link.zhihu.com/?targethttps%3A//www.wanyun.cn/Support%3Fshare%3D24315_ea8a0e47-b38d-4cd6-8ed1-9e7711a8ad5e 醫療器械源代碼審計是一個確保醫療器械軟件安全性和可靠性的重要過程。以下是醫療器械源代碼審計的主要步驟和要點,以…

Vue3 sortablejs 表格拖拽后,表格無法更新的問題處理

實用sortablejs在vue項目中實現表格行拖拽排序 你可能會發現,表格排序是可以實現,但是我們基于數據驅動的vue中關聯的數據并沒有發生變化, 如果你的表格帶有列固定(固定列實際上在dom中有兩個表格,其中固定的列在一個表格中&…

【Python】優雅的快速選擇 - 快速排序 - 隨機快速排序

快速選擇(遞歸實現版) 這里給出以 “leetcode215. 數組中的第K個最大元素”為例的代碼。 class Solution:def findKthLargest(self, nums, k):self.nums numsn len(nums)return self.quickSelect(0,n-1,n-k)def quickSelect(self,l,r,k): # 手擼快速…

Vue3實戰筆記(64)—Vue 3自定義指令的藝術:實戰中的最佳實踐

文章目錄 前言一、一些簡單的Vue3自定義指令超實用案例總結 前言 書接上文,在Vue3中,自定義指令是一種強大的工具,允許我們擴展HTML元素的功能。通過自定義指令,我們可以創建可重用的行為,并將它們綁定到任何元素上。…

訂單折扣金額分攤算法|代金券分攤|收銀系統|積分分攤|分攤|精度問題|按比例分配|錢分攤|錢分配

一個金額分攤的算法,將折扣分攤按比例(細單實收在總體的占比)到各個細單中。 此算法需要達到以下要求: 折扣金額接近細單總額,甚至折扣金額等于細單金額,某些時候甚至超過細單總額,要保證實收不…

游泳哪個牌子好?6大游泳耳機選購技巧總結分享

游泳耳機作為水上運動愛好者和游泳專業人士的必備裝備,不僅要能夠抵御水的侵入,還要提供清晰的音質和舒適的佩戴體驗。在市面上,不同品牌的游泳耳機琳瑯滿目,選擇起來可能會令人頭疼。本文旨在為您提供一份詳盡的游泳耳機選購指南…

每日一練 - Routing Policy節點邏輯

01 真題題目 一個 routing-policy 下可以有多個節點,不同節點號用 node 標識,每個節點下可以有多個if-match 和 apply 子句,下面哪些描述是錯誤的? A. 不同節點之間是“或"的關系 B. 當路由與該節點的任意一個 if-match 條件匹配失敗后,系統自動轉入下一節點…

Gemma輕量級開放模型在個人PC上釋放強大性能,讓每個桌面秒變AI工作站

Google DeepMind團隊最近推出了Gemma,這是一個基于其先前Gemini模型研究和技術的開放模型家族。這些模型專為語言理解、推理和安全性而設計,具有輕量級和高性能的特點。 Gemma 7B模型在不同能力領域的語言理解和生成性能,與同樣規模的開放模型…

名企專訪|對抗價格內卷,格行隨身WiFi如何持續三年爆火引領潮流

近期要是問網紅達人最喜歡帶貨的單品是什么?那一定有格行隨身WiFi的一席之地。能聚集了如此多的明星達人,僅僅是一句帶貨收益高顯然無法說服大家。顯然這里面還有著不為人知的秘密,先鋒財經特意專訪了格行隨身WiFi的創始人劉永先先生&#xf…

8.x86游戲實戰-OD詳解

免責聲明:內容僅供學習參考,請合法利用知識,禁止進行違法犯罪活動! 本次游戲沒法給 內容參考于:微塵網絡安全 上一個內容:7.x86游戲實戰-C實現跨進程讀寫-跨進程寫內存 工具下載:下載 OllyI…