Android工廠模式

前言

工廠模式是創建型模式,使我們常用/常見的模式之一。多用于需要生成復雜對象的地方。用new就可以完成創建的對象就無需使用。工廠模式降低了對象之間的耦合度,由于工廠模式依賴抽象的架構,實例化的任務交由子類去完成,所以有很好的擴展性。

工廠模式

定義:一個用于創建對象的接口,讓子類決定實例化哪個類
工廠模式一般也就兩大類:
普通工廠模式:生產具體的產品,創建的產品是類(Class)。
抽象工廠模式:生產抽象的產品,創建的產品是接口(Interface)。
一開始你可能理解不上來,當你看完這篇文章,你理解了,其實他們并不復雜,我們先來看一個普通工廠的例子
(這里擴展一點,雖然普通工廠表面上創建的是抽象類,但java特性里抽象類是不能被實例化的。我沒每次創建的時候,實際上是以匿名內部類的方式創建。實際是它繼承并創建的一個新的類。所以它僅僅是一個普通工廠)

普通工廠模式舉例

我們舉一個生產Nokia手機的例子。

public abstract class NokiaPhone {public abstract void powerOnPhone();
}

先試定義了一個抽象類,抽象出方法powerOnPhone(),模擬手機開機的動作。(ps:抽象類作用簡單點說就是抽象出一些方法,需要子類去實現,自己不能實現。起到一個抽象的作用)
然后我們定義具體的手機

public class Nokia5200 extends NokiaPhone {@Overridepublic void powerOnPhone() {Log.d("Factory","Nokia5200 power on");}
}public class NokiaN97 extends NokiaPhone{@Overridepublic void powerOnPhone() {Log.d("Factory","NokiaN97 power on");}
}

然后我們定義了具體的手機Nokia5200和NokiaN97兩款手機。并實現了抽象方法powerOnPhone
現在產品定義好了,我們就要定義工廠了,首先我們也抽象出工廠的方法

public abstract class Factory {public abstract <T extends NokiaPhone> T createNokia(Class<T> clz);
}

工廠的方法無非就是生產手機,所以我們抽象出來了createNokia方法,現在我們來定義工廠

public class NokiaFactory extends Factory {@Overridepublic <T extends NokiaPhone> T createNokia(Class<T> clz) {NokiaPhone nokiaPhone = null;try {nokiaPhone = (NokiaPhone) Class.forName(clz.getName()).newInstance();} catch (Exception e) {e.printStackTrace();} return (T) nokiaPhone;}
}

NokiaFactory工廠也很簡單就實現了抽象方法createNokia,來生產不同的手機。這里我們使用了反射方法

nokiaPhone = (NokiaPhone) Class.forName(clz.getName()).newInstance();

這句話的意思是通過類名(ClassName)來實例化具體的類,用的是反射機制來實現。
然后我們來看看我們怎么用工廠生產手機。

NokiaFactory nokiaFactory = new NokiaFactory();
Nokia5200 nokia5200 = nokiaFactory.createNokia(Nokia5200.class);
NokiaN97 nokiaN97 = nokiaFactory.createNokia(NokiaN97.class);

我們用工廠創建了兩個手機,一個nokia5200,一個nokiaN97。然后我們開機試試

nokia5200.powerOnPhone();
nokiaN97.powerOnPhone();

看log

D/Factory: Nokia5200 power on
D/Factory: NokiaN97 power on

至此,一個工廠模式就寫完了,可以看到工廠模式的代碼結構其實很簡單。有的讀者可能會想為啥NokiaFactory為啥要用反射呢,其實用反射主要是為了代碼簡潔,如果不這么寫,你可能像下面的代碼這樣寫

// 方案一
public class NokiaFactoryNokia5200 extends Factory {@Overridepublic <T extends NokiaPhone> T createNokia() {Nokia5200 nokia5200 = new Nokia5200();return (T) nokia5200;}
}public class NokiaFactoryNokiaN97 extends Factory {@Overridepublic <T extends NokiaPhone> T createNokia() {NokiaN97 nokiaN97 = new NokiaN97();return (T) nokiaN97;}
}
// 方案二
public class NokiaFactory extends Factory {@Overridepublic <T extends NokiaPhone> T createNokia(Class<T> clz) {Log.d("Factory",clz.getSimpleName());if (clz.getSimpleName().equals("Nokia5200")) {Nokia5200 nokia5200 = new Nokia5200();return (T) nokia5200;} else if (clz.getSimpleName().equals("NokiaN97")) {NokiaN97 nokiaN97 = new NokiaN97();return (T) nokiaN97;}return null;}
}
普通工廠模式小結

1、上面兩種方案,一是為每個手機單獨創建一個工廠,或者通過帶入的class來選擇創建都能實現,但是如果手機型號過多,代碼就顯得很長,當然最好還是用反射的方法,這里只是為了進行一個說明。
2、上面NokiaFactoryNokia5200、NokiaFactoryNokiaN97這種情況也有適合用這種方式的地方。我們下面講解抽象工廠的時候就會用不同工廠對應不同產品的方式來創建。并非一定是反射的方法。
3、最開始的例子還可以省略抽象方法,抽象方法只是為了更具體化,不過不建議這么做,抽象方法使我們的NokiaPhone更規范。代碼可讀性也更好。
4、普通工廠模的創建的產品是具體的類,這個例子的產品是NokiaPhone.class,雖然它是一個抽象類,但使用時已經創建的匿名內部類是一個具體的類。

抽象工廠模式例子

抽象工廠我們舉例一個生產Iphone零件的例子。
我們先定義產品,這里是生產零件,我們定義兩個抽象產品,一個CPU,一個電池。這里我把兩個接口寫在了一起,當然你也可以分開寫成兩個。

public interface component {public interface CPU {void showCpuName();}public interface Battery {void showBatteryCapacity();}
}

然后我們定義CPU的具體產品,一個A9,一個A10

public class A9 implements component.CPU {@Overridepublic void showCpuName() {Log.d("AbstractFactory","A9");}
}public class A10 implements component.CPU {@Overridepublic void showCpuName() {Log.d("AbstractFactory","A10");}
}

然后是兩種電池產品,一個1000ma,一個1200ma

public class Battery1000ma implements component.Battery {@Overridepublic void showBatteryCapacity() {Log.d("AbstractFactory","battery is 1000ma");}
}
public class Battery1200ma implements component.Battery {@Overridepublic void showBatteryCapacity() {Log.d("AbstractFactory","battery is 1200ma");}
}

產品定義好了,我們來定義工廠了,依舊先用抽象類,抽象出工廠類的方法

public abstract class Factory {public abstract component.CPU createCPU();public abstract component.Battery createBattery();
}

注意一點這里的抽象方法跟抽象工廠模式并無實際關系,不是因為這里使用抽象類而因此叫抽象工廠模式,而是因為工廠模式生產的產品。一個是component.CPU,一個是component.Battery。他們兩個都是接口,都是抽象出來的,抽象工廠模式因此而來。
雖然java特性里,抽象類和接口不都能實例化。都是創建匿名內部類方式來創建對象,但普通工廠創建的是抽象類,還是對象的一種描述,而抽象工廠思想上還是創建的接口。接口編程,由此特性所以它叫抽象工廠。
接著我們看具體工廠的實現,這里我們將用不同的工廠對應不同的產品來舉例

public class IPhone6Factory extends Factory {@Overridepublic component.CPU createCPU() {return new A9();}@Overridepublic component.Battery createBattery() {return new Battery1000ma();}
}public class Iphone7Factory extends Factory {@Overridepublic component.CPU createCPU() {return new A10();}@Overridepublic component.Battery createBattery() {return new Battery1200ma();}
}

1、可以看到IPhone6Factory和Iphone7Factory兩個工廠模式他們創建的產品相同,都是創建CPU和Battery這兩個抽象產品。而這兩個抽象產品又可以是同接口不同子類實例。

抽象工廠模式小結

1、抽象工廠模式創建的產品是接口,抽象出來的。
2、上面的例子其實跟普通工廠模式例子沒太大的差別,除了產品不同,實現的思想都是一樣的,只是這里用了不同的工廠對應不同的產品。普通工廠模式也可以這樣用。
3、抽象工廠有一個顯著的優點是分離接口與實現,用戶根本不知道具體的實現是誰,客戶僅僅是面向接口編程,使其從產品實現解耦,抽象工廠模式在切換產品類的時候更加靈活容易。

結束語

1、現在理解文章最開始的那句話是不是很好理解了
普通工廠模式:生產具體的產品,創建的產品是類(Class)
抽象工廠模式:生產抽象的產品,創建的產品是接口(Interface)
2、工廠模式的優點在上述兩個例子的小結中已經闡述,工廠模式的缺點也比較明顯,就是不太容易擴展新的產品類,需要去改具體的產品類和工廠類。
3、雖然美中不足,但工廠模式是運用非常廣泛的一種模式。值得大家學習使用。

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

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

相關文章

【AI面試準備】數據驅動測試思維與實踐指南

面試題&#xff1a;數據驅動思維 構建測試數據集&#xff1a;收集代碼覆蓋率、缺陷歷史等數據。 模型訓練優化&#xff1a;使用Jupyter Notebook分析特征重要性。 數據驅動思維是一種以數據為核心、基于數據分析結果進行決策的方法論。它強調通過量化分析、模式識別和預測建模…

內存碎片深度剖析

目錄 什么是內存碎片 內部碎片的解決 malloc STL二級空間配置器 外部碎片的解決 伙伴系統算法 slab分配器 什么是內存碎片 內存碎片是指在內存中存在的一些不連續的、較小的空閑內存塊&#xff0c;這些小塊內存由于太小而無法被有效地分配給程序使用&#xff0c;從而導…

flutter 專題 六十一 支持上拉加載更多的自定義橫向滑動表格

在股票軟件中&#xff0c;經常會看到如下所示的效果&#xff08;ps&#xff1a;由于公司數據敏感&#xff0c;所以使用另一個朋友的一個圖&#xff09;。 分析需要后&#xff0c;我先在網上找了下支持橫向滑動的組件&#xff0c;最后找到了這個&#xff1a;flutter_horizontal…

0-1背包問題基礎概念

一、問題描述 給定一個容量為 W 的背包和 n 個物品。每個物品有一個重量 w[i] 和價值 v[i]。每個物品只能選或不選&#xff08;即“0-1”&#xff09;&#xff0c;求在不超過背包容量的前提下&#xff0c;所能獲得的最大總價值。 輸入&#xff1a; 背包容量 W&#xff08;in…

使用 Semantic Kernel 快速對接國產大模型實戰指南(DeepSeek/Qwen/GLM)

文章目錄 使用 Semantic Kernel 快速對接國產大模型實戰指南&#xff08;DeepSeek/Qwen/GLM&#xff09;一、引言二、環境準備2.1 開發環境2.2 模型服務配置 三、核心代碼實現3.1 會話代碼封裝3.2 CurModelContext封裝3.3 DeepSeek對接示例3.4 Qwen對接示例3.5 GLM對接示例 四、…

Ai時代,運維人如何轉型

在AI時代,傳統運維向智能運維(AIOps)的轉型需要系統性重塑,以下是深度拆解的轉型路線圖和關鍵實施要素: 一、認知升級范式轉變 1. 演進路線模型(三階段) 被動響應階段:人工巡檢(→監控覆蓋率<30%)主動防御階段:規則引擎(→告警準確率70%~85%)預測自治階段:深…

windows鼠標按鍵自定義任意設置

因為用慣了Linux的鼠標中鍵的復制黏貼&#xff0c;發現windows下有完全可以實現類似自定義功能的軟件&#xff0c;推薦一下&#xff1a; X Mouse Button Control。 免費版足夠好用。 軟件簡介&#xff1a; X Mouse Button Control是一款專業的重新映射鼠標按鈕的軟件工具&…

怎么看戶型好不好?

看房型好不好可從以下方面判斷&#xff1a; 空間布局 方正性&#xff1a;戶型方正為佳 &#xff0c;此時進深與開間比例在1:1.5左右。方正戶型空間利用率高&#xff0c;無采光死角。如手槍型、鋸齒型等異形戶型&#xff0c;易有拐角、長過道&#xff0c;空間浪費大。動靜分區…

基于WOA鯨魚優化TCN-BiGRU注意力機制網絡模型的時間序列預測算法matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 matlab2022a/matlab2024b 3.部分核心程序 &#xff08;完整版代碼包含詳細中文注釋和操作步驟視頻…

JAVA簡單走進AI世界~Spring AI

1、背景 現代 AI 正以前所未有的速度改變著世界。它是基于復雜算法和強大計算能力的技術體系,涵蓋了機器學習、深度學習、自然語言處理等多個領域。 在日常生活中,AI 廣泛應用于智能語音助手、圖像識別、推薦系統等。比如,智能音箱能理解并回應語音指令,為人們提供信息查…

stm32wb55rg (4) 啟用usart串口

code repo: 訪問gitee 上節課成功點亮了LED&#xff0c;這次來把usart 用起來&#xff0c;畢竟有交互才是系統。 技術準備 首先查看手冊&#xff0c;發現mcu有1個usart和1個 lpuart。 usart 的使用需要兩個pin&#xff0c;一個接收一個發送。繼續查看pin and ball definition…

Python生活手冊-NumPy數組創建:從快遞分揀到智能家居的數據容器

一、快遞分揀系統&#xff08;列表/元組轉換&#xff09; 1. 快遞單號錄入&#xff08;np.array()&#xff09; import numpy as np快遞單號入庫系統 快遞單列表 ["SF123", "JD456", "EMS789"] 快遞數組 np.array(快遞單列表) print(f"…

數據庫-數據類型,表的約束和基本查詢操作

一、數值類型 1. 整數類型 類型字節有符號范圍無符號范圍操作注意事項TINYINT1-128 ~ 1270 ~ 255默認有符號&#xff0c;UNSIGNED定義無符號SMALLINT2-32768 ~ 327670 ~ 65535無符號需顯式聲明INT4-2^31 ~ 2^31-10 ~ 2^32-1推薦優先使用INTBIGINT8-2^63 ~ 2^63-10 ~ 2^64-1存…

【C語言編譯】編譯原理和詳細過程

文章目錄 1. C 語言編譯原理和詳細過程1.1 預處理階段1.2 編譯階段1.3 匯編階段1.4 鏈接階段 2. 疑問點解析2.1 三地址碼是什么&#xff1f;有什么作用2.2 符號表是什么&#xff1f;有何作用2.3 重定位的含義與作用2.3 符號表和重定位在整個編譯過程中的作用2.4 動態鏈接庫.so和…

游戲引擎學習第251天:完成調試層級結構

運行游戲&#xff0c;查看當前調試層級的狀態。 我們正在直播中開發一個完整的游戲&#xff0c;目前正進行調試代碼的整理和清理工作。現在我們直接進入正題&#xff0c;雖然還不完全確定今天要完成哪些具體內容&#xff0c;但有幾個明確的目標&#xff1a; 首先&#xff0c;…

關于Python:9. 深入理解Python運行機制

一、Python內存管理&#xff08;引用計數、垃圾回收&#xff09; Python&#xff08;CPython&#xff09;采用的是&#xff1a; “引用計數為主&#xff0c;垃圾回收為輔” 的內存管理機制。 也就是說&#xff1a; 引用計數機制&#xff1a;負責大部分內存釋放&#xff0c;簡…

【STM32單片機】#13 RTC實時時鐘

主要參考學習資料&#xff1a; B站江協科技 STM32入門教程-2023版 細致講解 中文字幕 開發資料下載鏈接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 單片機套裝&#xff1a;STM32F103C8T6開發板單片機C6T6核心板 實驗板最小系統板套件科協 目錄 Uni…

SecureCRT 使用指南:安裝、設置與高效操作

目錄 一、SecureCRT 簡介 1.1 什么是 SecureCRT&#xff1f; 1.2 核心功能亮點 1.3 軟件特點 二、SecureCRT 安裝與激活 2.1 安裝步驟&#xff08;Windows 系統&#xff09; 2.2 激活與破解&#xff08;僅供學習參考&#xff09; 三、基礎配置與優化 3.1 界面與編碼設…

3.5/Q1,GBD數據庫最新一區文章解讀

文章題目&#xff1a;Global burden of low vision and blindness due to age-related macular degeneration from 1990 to 2021 and projections for 2050 DOI&#xff1a;10.1186/s12889-024-21047-x 中文標題&#xff1a;1990年至2021年因年齡相關性黃斑變性導致的低視力和失…

【Hive入門】Hive安全管理與權限控制:基于SQL標準的授權GRANT REVOKE深度解析

目錄 引言 1 Hive權限模型概述 2 SQL標準授權基礎 2.1 核心概念解析 2.2 授權模型工作流程 3 GRANT/REVOKE語法詳解 3.1 基礎授權語法 3.2 權限回收語法 3.3 參數說明 4 授權場景 4.1 基礎授權示例 4.2 列級權限控制 4.3 視圖權限管理 5 權限查詢與驗證 5.1 查看…