Java設計模式之(工廠模式)--簡單工廠模式--工廠方法模式--抽象工廠模式

工廠模式:


工廠模式可以分為三類:

1)簡單工廠模式(Simple Factory)
2)工廠方法模式(Factory Method)
3)抽象工廠模式(Abstract Factory)


簡單工廠模式

插頭 分為二孔插頭和三孔插頭。
首先 創建插頭產品類 Pin

public class Pin {protected String PinType;
}

然后分別創建二孔插頭和三孔插頭類

/**
* @author hjn
*二孔插頭類
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}/**
* @author hjn
*三孔插頭類
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}
public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");} }

然后創建插頭工廠類

/**
* @author hjn
*插頭工廠類
*/
public class PinFactory {/*** @param type* @return* 根據插頭數返回相對的插頭對象*/public static Pin creatPin(int type) {switch (type) {case 2:return new PinTw();case 3:return new PinTh();default:break;}return null;}
}

最后 測試類 :

public class TestPin {public static void main(String[] args) {Pin pinth = PinFactory.creatPin(3);Pin pintw = PinFactory.creatPin(2);}
}        

?

這就是簡單工廠模式。

簡單工廠模式又稱靜態工廠方法模式。重命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用于創建對象的接口。
先來看看它的組成:
1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯,用來創建產品
2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。
3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在Java中由一個具體類實現。

下面我們從開閉原則(對擴展開放;對修改封閉)上來分析下簡單工廠模式。當客戶不再滿足現有的插頭型號的時候,想要一種更多頭的新型插頭,只要這種插頭符合抽象產品制定的合同,那么只要通知工廠類知道就可以被客戶使用了。所以對產品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因為每增加一種新型插頭,都要在工廠類中增加相應的創建業務邏輯(creatPin(int type)方法需要新增case),這顯然是違背開閉原則的。可想而知對于新產品的加入,工廠類是很被動的。對于這樣的工廠類,我們稱它為全能類或者上帝類。
我們舉的例子是最簡單的情況,而在實際應用中,很可能產品是一個多層次的樹狀結構。由于簡單工廠模式中只有一個工廠類來對應這些產品,所以這可能會把我們的上帝累壞了,也累壞了我們這些程序員。
于是工廠方法模式作為救世主出現了。 工廠類定義成了接口,而每新增的插頭種類型,就增加該插頭種類型對應工廠類的實現,這樣工廠的設計就可以擴展了,而不必去修改原來的代碼。

簡單工廠模式的優缺點
 優點:客戶端不需要修改代碼。
 缺點: 當需要增加新的運算類的時候,不僅需新加運算類,還要修改工廠類,違反了開閉原則。


工廠方法模式

工廠方法模式去掉了簡單工廠模式中工廠方法的靜態屬性,使得它可以被子類繼承。這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔。
工廠方法模式組成:
1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。
2)具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。
3)抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在java中一般有抽象類或者接口來實現。
4)具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在java中由具體的類來實現。
工廠方法模式使用繼承自抽象工廠角色的多個子類來代替簡單工廠模式中的“上帝類”。正如上面所說,這樣便分擔了對象承受的壓力;而且這樣使得結構變得靈活 起來——當有新的產品產生時,只要按照抽象產品角色、抽象工廠角色提供的合同來生成,那么就可以被客戶使用,而不必去修改任何已有 的代碼。可以看出工廠角色的結構也是符合開閉原則的!

首先 創建插頭產品類 Pin

public class Pin {protected String PinType;
}

?

然后分別創建二孔插頭和三孔插頭類

/**
* @author hjn
*二孔插頭類
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}/**
* @author hjn
*三孔插頭類
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");}
}

然后創建插頭工廠接口:

/**
* @author hjn
* 工廠方法接口*
*/
public interface IPinFactory {public Pin creatPin();}

然后創建 二孔插頭和三孔插頭的工廠

?

/**
* @author hjn
*二孔的工廠類 
*/
public class PinTwFactory implements IPinFactory {Pin ptw=new PinTw();public Pin creatPin() {    return ptw;}
}/**
* @author hjn
*三孔的工廠類
*/
public class PinThFactory implements IPinFactory {Pin pth=new PinTh();public Pin creatPin() {    return pth;}
}

?

測試類 :

?

public class TestPin {public static void main(String[] args) {PinThFactory pthf =new PinThFactory();Pin pinth = pthf.creatPin();PinTwFactory ptwf=new PinTwFactory();Pin pintw = ptwf.creatPin();}
}

?

這個和簡單工廠有區別,簡單工廠模式只有一個工廠,工廠方法模式對每一個產品都有相應的工廠,當產品種類非常多時,會出現大量的與之對應的工廠對象,這不是我們所希望的。

  好處:增加一個運算類(例如N次方類),只需要增加運算類和相對應的工廠,兩個類,不需要修改工廠類。
  缺點:增加運算類,會修改客戶端代碼,工廠方法只是把簡單工廠的內部邏輯判斷移到了客戶端進行。


抽象工廠模式

首先 創建插頭產品類 Pin

public class Pin {protected String PinType;
}

然后分別創建二孔插頭和三孔插頭類

/**
* @author hjn
*二孔插頭類
*/
public class PinTw extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTw() {System.out.println("I am 2孔 Pin");}
}
 
/**
* @author hjn
*三孔插頭類
*/
public class PinTh extends Pin {private String PinType;public String getPinType() {return PinType;}public void setPinType(String pinType) {PinType = pinType;}public PinTh() {System.out.println("I am 3孔 Pin");}
}

?


然后創建插頭工廠接口:

/**
* @author hjn
* 工廠方法接口*
*/
public interface IPinFactory {public Pin creatPinTw();public Pin creatPinTh();
} /**
* @author hjn
*Pin工廠實現類
*/
public class PinFactoryImpl implements IPinFactory {@Overridepublic Pin creatPinTw() {return new PinTw();}@Overridepublic Pin creatPinTh() {    return new PinTh();}}

?

測試類

public class TestPin {public static void main(String[] args) {PinFactoryImpl pin = new PinFactoryImpl();Pin ptw = pin.creatPinTw();Pin pth = pin.creatPinTh();}
}

?

 抽象工廠模式,一個具體工廠可以制造幾個產品

優點:易于交換產品系列,例如Access和SQLServer數據庫之間切換。
  缺點:如果需要增加新的產品樹,那么就要新增三個產品類,并且要修改三個工廠類。這樣大批量的改動是很丑陋的做法。


工廠方法模式:
一個抽象產品類,可以派生出多個具體產品類。
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類只能創建一個具體產品類的實例。
抽象工廠模式:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類可以創建多個具體產品類的實例。


區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。
工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。

轉載于:https://www.cnblogs.com/caixiaohua/p/6760389.html

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

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

相關文章

今天很多 CTO 都是被干掉的,因為他沒有成就業務

作者|喬新亮 編輯|鄧艷琴 我可以絲毫不開玩笑地說,今天,很多傳統企業里的研發都只是“工人”,哪怕是 CTO,充其量也只是“高級工人”,如果不轉換思維去成就業務,就只能停留在工人級…

中航工業集團金網絡(北京)電子商務有限公司副總經理劉正珩:航空“智”造的供應鏈支撐平臺...

編者按 “十三五”時期是我國貿易發展的重要戰略機遇期,物流產業發展迅速,智慧供應鏈已經成為推動流通大國向流通強國過程中的重要行動。6月2日,由上海市國有資產監督管理委員會、上海市郵政管理局、上海市商務委員會指導,上海市國…

創建、檢查和反編譯世界上(幾乎)最短的 C# 程序

創建、檢查和反編譯世界上(幾乎)最短的 C# 程序原文來自https://www.stevejgordon.co.uk/creating-inspecting-decompiling-the-worlds-smallest-csharp-program在這篇文章中,我認為創建世界上(幾乎)最短的 C# 程序然后…

Linux下畫原理圖和PCB

Linux下畫原理圖和PCBWindows下大名鼎鼎的Allegro和經典的Protel 99SE都是不支持Linux操作系統的。做Linux驅動開發免不了要看一下原理圖和PCB。一般的做法有三種: 1.主機使用Windows系統,將Linux裝在VMWARE之類的虛擬機中這樣能夠使用Windows下的軟件看…

配置中心 App Configuration (二):Feature Flag 功能開關特性

寫在前面Web服務開發過程中我們經常有這樣的需求:某些功能我必須我修改了配置才啟用,比如新用戶注冊送券等;某個功能需到特定的時間才啟用,過后就失效,比如春節活動等;某些功能,我想先對10%的用…

oracle臨時表空間

--查看臨時表空間SELECT * FROM v$tablespace;SELECT * FROM dba_tablespaces;--查看所有臨時表空間文件SELECT * FROM dba_data_files;--查看臨時臨時表空間文件SELECT * FROM dba_temp_files;--查看臨時表空間組SELECT * FROM dba_tablespace_groups; --查找默認臨時表空間SE…

ES 2022 正式發布!有哪些新特性?

2022 年 6 月 22 日,第 123 屆 Ecma 大會批準了 ECMAScript 2022 語言規范[1],這意味著它現在正式成為標準。 1 ECMAScript 2022編輯 本次發布的編輯有: Shu-yu Guo[2] Michael Ficarra[3] Kevin Gibbons[4] 2 ECMAScript 2022有什么新內…

聯想(Lenovo)小新310經典版進bios方法

1,找到novo按鈕。 2,在關機的狀態下桶一下小孔,不用任何操作,電腦進入bios選擇界面。轉載于:https://www.cnblogs.com/senior-engineer/p/6761457.html

C#中的匿名類型

這節來講一下C#中的匿名類型。匿名類在C#中,我們可以不去顯示的聲明一個類,而是通過匿名類去臨時聲明一個類結構去幫助我們去完成一些功能。聲明一個匿名類,我們可以像下面這樣做:var Anonymousnew {name"charles",year…

MySQL之MHA高可用集群

目錄 一、MHA概述 1.1.MHA 是什么 1.2.MHA 的組成 1.3.MHA 的特點 二、MHA搭建準備 2.1.實驗思路 三、MHA搭建 3.1配置主從復制 3.2.安裝 MHA 軟件 3.3.故障模擬 3.4.故障修復 四、總結 一、MHA概述 1.1.MHA 是什么 1.MHA(MasterHigh Availability&…

Tensorflow之安裝

1.fellow the instruction of https://www.tensorflow.org/install/install_linux#installing_with_anaconda 2.anaconda安裝,修改~/.bash_profile為 export PATH~/anaconda2/bin:/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRAR…

2、Saltstack的數據系統

一、Grainsgrains是salt用來收集minion端底層系統信息的接口。比如,操作系統type、域名 、IP地址、內存及其他相關系統屬性信息等。存儲在minion端,用于保存minion端數據信息。minion啟動時才加載grains信息,所以他時靜態的,Grain…

配置中心 App Configuration (一):輕松集成到Asp.Net Core

寫在前面在日常開發中,我這邊比較熟悉的配置中心有,攜程Apollo,阿里Nacos(配置中心,服務治理一體)之前文章:Asp.Net Core與攜程阿波羅(Apollo)的第一次親密接觸總體來說,Apollo和Nacos社區都比較活躍&#…

stop-hbase.sh一直處于等待狀態

今天關閉HBase時,輸入stop-hbase.sh一直處于等待狀態 解決方法: 先輸入:hbase-daemon.sh stop master 再輸入:stop-hbase.sh就可以關閉HBase集群了。 轉載于:https://www.cnblogs.com/lijinze-tsinghua/p/8667761.html

shell編程100例

1、編寫hello world腳本 #!/bin/bash# 編寫hello world腳本echo "Hello World!"2、通過位置變量創建 Linux 系統賬戶及密碼 #!/bin/bash# 通過位置變量創建 Linux 系統賬戶及密碼#$1 是執行腳本的第一個參數,$2 是執行腳本的第二個參數 useradd "$1" …

sqlserver 分頁

select top 10 numComImg.* from( select row_number() over(order by id asc) as rownumber,* from (select * FROM [TCCLine].[dbo].[CLine_CommonImage]) as comImg)as numComImg where rownumber>40select top 10 * --10 為頁大小from [TCCLine].[dbo].[CLine_CommonIma…

詳解SpringMVC中Controller的方法中參數的工作原理[附帶源碼分析] good

目錄 前言現象源碼分析 HandlerMethodArgumentResolver與HandlerMethodReturnValueHandler接口介紹HandlerMethodArgumentResolver與HandlerMethodReturnValueHandler接口的具體應用常用HandlerMethodArgumentResolver介紹常用HandlerMethodReturnValueHandler介紹本文開頭現象…

instancing render

當要繪制同一個東西很多次的時候,最簡單的想法可能是循環調用glDrawArrays(),但這樣會造成性能的損失。因為當顯卡在渲染一個物體的時候,可能并不需要太多時間,但系統會花大量的時間,頻繁的調用draw命令,再…

對不起,我不是一個自律的人

大家好,我是 🐟💨。前天,星球 的一位大學生朋友問了我幾個問題:你大學時如何安排每日的時間?為什么能學那么多技術?你會學習到很晚嗎?你是如何保持自律的?我覺得這幾個問…

保證接口數據安全的10種方案

前言 大家好,我是程序汪,互聯網項目需要特別注意數據安全,如果你簡歷上是互聯網類型項目,安全方面肯定要能說出個一二三,下面分享下這方面的干貨,大家可以記住幾條,面試時好說道說道 我們日常…