🎈🎈🎈🎈🎈往期推薦:
🎉《23種設計模式(Java版)》| 設計模式相關簡介,
🎉《23種設計模式(Java版)》| 單例模式(內附原始碼案例),
2021 年 12 月 25日
百思不得小趙 🔍點擊進入博客首頁
—— 新時代的農民工 🙊
—— 換一種思維邏輯去看待這個世界 👀
今天是加入CSDN的第1029天,覺得有幫助麻煩👏點贊、🍀評論、??收藏啦,
?目錄
- 💎 一、概述
- 📕 二、工廠模式的三種方式
- 🏭 簡單工廠
- 🔨 工廠方法
- 🪓 抽象工廠
- 📄 三、在JDK原始碼中的應用分析
- 📢 四、總結Tips

💎 一、概述
工廠模式是我們最常用的實體化物件模式了,是用工廠方法代替new操作的一種模式,著名的Jive論壇 ,就大量使用了工廠模式,工廠模式在Java程式系統可以說是隨處可見,因為工廠模式就相當于創建實體物件的new,我們經常要根據類Class生成實體物件,如A a=new A() 工廠模式也是用來創建實體物件的,所以以后new時就要多個心眼,是否可以考慮使用工廠模式,雖然這樣做,可能多做一些作業,但會給你系統帶來更大的可擴展性和盡量少的修改量---------來源于百度百科,
📕 二、工廠模式的三種方式
🏭 簡單工廠
- 簡單工廠模式是屬于創建型模式,是工廠模式的一種,簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的實體,簡單工廠模式是工廠模式家族中最簡單實用的模式
- 簡單工廠模式:定義了一個創建物件的類,由這個類來封裝實體化物件的行為(代碼)
- 在軟體開發中,當我們會用到大量的創建某種、某類或者某批物件時,就會使用到工廠模式
案例代碼:
//定義一個公共介面
public interface Car {
void gotoWork();
}
public class Bus implements Car{
@Override
public void gotoWork() {
// TODO Auto-generated method stub
System.out.println("坐公交上班");
}
}
public class Bike implements Car{
@Override
public void gotoWork() {
// TODO Auto-generated method stub
System.out.println("騎自行車上班");
}
}
//簡單工廠類
public class SimpleFactory {
public enum CarType{
Bike,Bus;
}
//通過不同的方式構建不同的實體
public static Car getCar(CarType car) {
Car simpleCar=null;
switch(car) {
case Bike:
simpleCar=new Bike();
break;
case Bus:
simpleCar= new Bus();
break;
default:
simpleCar=new Bike();
}
return simpleCar;
}
}
🔨 工廠方法
通過一個需求案例:
看一個披薩的專案:要便于披薩種類的擴展,要便于維護
1.披薩的種類很多(比如 GreekPizz、CheesePizz 等
2.披薩的制作有 prepare,bake, cut, box
3.完成披薩店訂購功能
客戶在點披薩時,可以點不同口味的披薩,比如 北京的奶酪pizza、
北京的胡椒pizza 或者是倫敦的奶酪pizza、倫敦的胡椒pizza,
- 工廠方法模式設計方案:將披薩專案的實體化功能抽象成抽象方法,在不同的口味點餐子類中具體實作,
- 工廠方法模式:定義了一個創建物件的抽象方法,由子類決定要實體化的類,工廠方法模式將物件的實體化推遲到子類

案例代碼:
public abstract class Pizza {
protected String name;
//準備材料,不同的披薩材料不一樣,做成抽象方法
public abstract void prepare();
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
public class BJCheesePizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的奶酪披薩");
System.out.println("北京的奶酪披薩準備原材料");
}
}
public class BJGreekPizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的希臘披薩");
System.out.println("北京的希臘披薩準備原材料");
}
}
public class LDCheesePizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦奶酪披薩");
System.out.println("倫敦奶酪披薩準備原材料");
}
}
public class LDGreekPizz extends Pizza
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦希臘披薩");
System.out.println("倫敦希臘披薩準配原材料");
}
}
public abstract class OrderPizza {
//定義一個抽象方法,讓各個工廠子類自己實作
abstract Pizza creatPizza(String orderType);
//構造器
public OrderPizza() {
Pizza pizza = null;
// 訂購披薩型別
String orderType;
do {
orderType = getType();
pizza=creatPizza(orderType);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
// 動態的獲取用戶希望訂購的披薩
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
public class BJOrderPizza extends OrderPizza{
@Override
Pizza creatPizza(String orderType) {
Pizza pizza=null;
if(orderType.equals("cheese")) {
pizza=new BJCheesePizz();
}else if(orderType.equals("greek")) {
pizza=new BJGreekPizz();
}
return pizza;
}
}
public class LDOrderPizza extends OrderPizza{
@Override
Pizza creatPizza(String orderType) {
Pizza pizza=null;
if(orderType.equals("cheese")) {
pizza=new LDCheesePizz();
}else if(orderType.equals("greek")) {
pizza=new LDGreekPizz();
}
return pizza;
}
}
public class PizzaStore {
public static void main(String[] args) {
// TODO Auto-generated method stub
//創建北京口味的披薩
// new BJOrderPizza();
//創建倫敦口味的披薩
new LDOrderPizza();
}
}
🪓 抽象工廠
- 抽象工廠模式:定義了一個interface用于創建相關或有依賴關系的物件簇,而無需指明具體的類
- 抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合,
- 從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象),
- 將工廠抽象成兩層,AbsFactory(抽象工廠) 和具體實作的工廠子類,程式員可以根據創建物件型別使用對應的工廠子類,這樣將單個的簡單工廠類變成了工廠簇,更利于代碼的維護和擴展,

?需求案例同工廠方法案例,抽象工廠對其進行進一步的優化,
案例代碼:
public abstract class Pizza {
protected String name;
//準備材料,不同的披薩材料不一樣,做成抽象方法
public abstract void prepare();
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
public class BJCheesePizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的奶酪披薩");
System.out.println("北京的奶酪披薩準備原材料");
}
}
public class BJGreekPizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的希臘披薩");
System.out.println("北京的希臘披薩準備原材料");
}
}
public class LDCheesePizz extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦奶酪披薩");
System.out.println("倫敦奶酪披薩準備原材料");
}
}
public class LDGreekPizz extends Pizza
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦希臘披薩");
System.out.println("倫敦希臘披薩準配原材料");
}
}
//抽象工廠模式的抽象層
public interface AbsFactory {
//下面工廠子類自己建造
Pizza creatPizza(String orderType);
}
public class BJFactory implements AbsFactory{
public Pizza creatPizza(String orderType) {
System.out.println("使用抽象工廠模式");
// TODO Auto-generated method stub
Pizza pizza=null;
if(orderType.equals("cheese")) {
pizza=new BJCheesePizz();
}else if(orderType.equals("greek")) {
pizza=new BJGreekPizz();
}
return pizza;
}
}
public class LDFactory implements AbsFactory{
public Pizza creatPizza(String orderType) {
System.out.println("使用抽象工廠模式");
// TODO Auto-generated method stub
Pizza pizza=null;
if(orderType.equals("cheese")) {
pizza=new LDCheesePizz();
}else if(orderType.equals("greek")) {
pizza=new LDGreekPizz();
}
return pizza;
}
public class OrderPizza {
AbsFactory absFactory;
public OrderPizza(AbsFactory absFactory) {
setAbsFactory(absFactory);
}
private void setAbsFactory(AbsFactory absFactory) {
Pizza pizza=null;
String orderType="";
this.absFactory = absFactory;
do {
orderType=getType();
//absFactory 可能為北京 或者倫敦
pizza=absFactory.creatPizza(orderType);
if(pizza!=null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}else {
System.out.println("訂購失敗");
break;
}
}while(true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
public class PizzaStore {
public static void main(String[] args) {
// TODO Auto-generated method stub
new OrderPizza(new BJFactory());
}
}
📄 三、在JDK原始碼中的應用分析
JDK 中的Calendar類中,就使用了簡單工廠模式
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
public static Calendar getInstance(TimeZone zone,
Locale aLocale){
return createCalendar(zone, aLocale);
}
private static Calendar createCalendar(TimeZone zone,
Locale aLocale){
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
}
📢 四、總結Tips
- 工廠模式的意義:將實體化物件的代碼提取出來,放到一個類中統一管理和維護,達到和主專案的依賴關系的解耦,從而提高專案的擴展和維護性,
- 三種工廠模式 (簡單工廠模式、工廠方法模式、抽象工廠模式)
- 設計模式的依賴抽象原則
- 創建物件實體時,不要直接 new 類, 而是把這個new 類的動作放在一個工廠的方法中,并回傳,有的書上說,變數不要直接持有具體類的參考,
- 不要讓類繼承具體類,而是繼承抽象類或者是實作interface(介面)、不要覆寫基類中已經實作的方法

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/393134.html
標籤:java
上一篇:IDEA中將SpringBoot專案提交到git倉庫
下一篇:十大排序總結(js實作、穩定性、內外部排序區別、時間空間復雜度、冒泡、快速、直接選擇、堆、直接插入、希爾、桶、基數、歸并、計數排序)
