Java?深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式
1.什么是抽象工廠模式?
- 抽象工廠模式: 定義了一個(gè)interface用于創(chuàng)建相關(guān)或有依賴關(guān)系的對(duì)象簇,而無需指明具體的類。
- 抽象工廠模式可以將簡(jiǎn)單工廠模式和工廠方法模式進(jìn)行整合。
- 從設(shè)計(jì)層面看,抽象工廠模式就是對(duì)簡(jiǎn)單工廠模式的改進(jìn)(或者稱為進(jìn)一步的抽象)。
- 將工廠抽象成兩層,AbsFactory(抽象工廠))和具體實(shí)現(xiàn)的工廠子類。程序員可以根據(jù)創(chuàng)建對(duì)象類型使用對(duì)應(yīng)的工廠子類。這樣將單個(gè)的簡(jiǎn)單工廠類變成了工廠簇,更利于代碼的維護(hù)和擴(kuò)展。
我們?nèi)匀灰陨弦黄恼碌陌咐秊橹?,畫出抽象工廠模式下的類圖。

2.案例代碼
首先仍然是Pizza種類相關(guān)的幾個(gè)類。
package com.szh.factory.abstractfactory.pizza;
/**
* 聲明Pizza類為抽象類
*/
public abstract class Pizza {
//Pizza名稱
protected String name;
//準(zhǔn)備原材料,不同的披薩不一樣。因此,我們做成抽象方法,具體的原材料實(shí)現(xiàn)交給它的子類去完成
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;
}
}
package com.szh.factory.abstractfactory.pizza;
public class LDPepperPizza extends Pizza {
@Override
public void prepare() {
setName("倫敦的胡椒pizza");
System.out.println("倫敦的胡椒pizza 準(zhǔn)備原材料");
}
}
package com.szh.factory.abstractfactory.pizza;
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
setName("倫敦的奶酪pizza");
System.out.println("倫敦的奶酪pizza 準(zhǔn)備原材料");
}
}
package com.szh.factory.abstractfactory.pizza;
public class BJPepperPizza extends Pizza {
@Override
public void prepare() {
setName("北京的胡椒pizza");
System.out.println("北京的胡椒pizza 準(zhǔn)備原材料");
}
}
package com.szh.factory.abstractfactory.pizza;
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
setName("北京的奶酪pizza");
System.out.println("北京的奶酪pizza 準(zhǔn)備原材料");
}
}下面是抽象工廠和工廠方法的區(qū)別之處。
package com.szh.factory.abstractfactory.order;
import com.szh.factory.abstractfactory.pizza.Pizza;
//一個(gè)抽象工廠模式的抽象層(接口)
public interface AbsFactory {
//讓下面的工廠子類來具體實(shí)現(xiàn)
public Pizza createPizza(String orderType);
}
package com.szh.abstractfactory.order;
import com.szh.abstractfactory.pizza.BJCheesePizza;
import com.szh.abstractfactory.pizza.BJPepperPizza;
import com.szh.abstractfactory.pizza.Pizza;
public class BJFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if("cheese".equals(orderType)) {
pizza = new BJCheesePizza();
} else if ("pepper".equals(orderType)){
pizza = new BJPepperPizza();
}
return pizza;
}
}
package com.szh.abstractfactory.order;
import com.szh.abstractfactory.pizza.LDCheesePizza;
import com.szh.abstractfactory.pizza.LDPepperPizza;
import com.szh.abstractfactory.pizza.Pizza;
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if ("cheese".equals(orderType)) {
pizza = new LDCheesePizza();
} else if ("pepper".equals(orderType)) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
package com.szh.factory.abstractfactory.order;
import com.szh.factory.abstractfactory.pizza.Pizza;
import java.util.Scanner;
public class OrderPizza {
AbsFactory absFactory;
public OrderPizza(AbsFactory absFactory) {
setFactory(absFactory);
}
private void setFactory(AbsFactory absFactory) {
Pizza pizza = null;
String orderType = ""; // 用戶輸入
this.absFactory = absFactory;
do {
orderType = getType();
// factory 可能是北京的工廠子類,也可能是倫敦的工廠子類
pizza = absFactory.createPizza(orderType);
if (pizza != null) { // 訂購(gòu)ok
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("訂購(gòu)失敗");
break;
}
} while (true);
}
// 寫一個(gè)方法,可以獲取客戶希望訂購(gòu)的披薩種類
private String getType() {
Scanner scanner = new Scanner(System.in);
System.out.println("請(qǐng)輸入 pizza 種類: ");
String str = scanner.nextLine();
return str;
}
}最后是測(cè)試類。
package com.szh.abstractfactory;
import com.szh.abstractfactory.order.BJFactory;
import com.szh.abstractfactory.order.LDFactory;
import com.szh.abstractfactory.order.OrderPizza;
import java.util.Scanner;
public class MainTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String content = scanner.next();
if ("Beijing".equals(content)) {
new OrderPizza(new BJFactory());
} else if ("London".equals(content)) {
new OrderPizza(new LDFactory());
} else {
System.out.println("無法預(yù)先匹配Pizza種類....");
scanner.close();
}
}
}
3.工廠方法 + 抽象工廠總結(jié)
- 工廠模式的意義:將實(shí)例化對(duì)象的代碼提取出來,放到一個(gè)類中統(tǒng)一管理和維護(hù),達(dá)到和主項(xiàng)目的依賴關(guān)系的解耦。從而提高項(xiàng)目的擴(kuò)展和維護(hù)性。
- 遵循了依賴倒轉(zhuǎn)原則:創(chuàng)建對(duì)象實(shí)例時(shí),不要直接new類,而是把這個(gè)new類的動(dòng)作放在一個(gè)工廠的方法中,并返回。有的書上說,變量不要直接持有具體類的引用。 不要讓類繼承具體類,而是繼承抽象類或者是實(shí)現(xiàn)interface(接口)不要覆蓋基類中已經(jīng)實(shí)現(xiàn)的方法。
到此這篇關(guān)于Java 深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式的文章就介紹到這了,更多相關(guān)Java 抽象工廠模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法
這篇文章主要介紹了spring cloud 使用Eureka 進(jìn)行服務(wù)治理方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(47)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-08-08
淺談Java中向上造型向下造型和接口回調(diào)中的問題
這篇文章主要介紹了淺談Java中向上造型向下造型和接口回調(diào)中的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
SpringBoot AOP導(dǎo)致service注入后是null的問題
本文主要講述了如何利用SpringAOP實(shí)現(xiàn)用戶操作日志的記錄,首先,引入SpringBoot的AOP依賴,然后,選擇基于注解的形式來實(shí)現(xiàn)日志操作,以避免污染原有代碼和邏輯,在理解了SpringBootAOP的一些注解后,需要記錄用戶的正常請(qǐng)求以及異常請(qǐng)求的信息2024-10-10
SpringData JPA Mongodb查詢部分字段問題
這篇文章主要介紹了SpringData JPA Mongodb查詢部分字段問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java設(shè)計(jì)模式之工廠模式(Factory模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之工廠模式(Factory模式)介紹,本文講解了為何使用工廠模式、工廠方法、抽象工廠、Java工廠模式舉例等內(nèi)容,需要的朋友可以參考下2015-03-03
Apache?Log4j2?報(bào)核彈級(jí)漏洞快速修復(fù)方法
Apache?Log4j2?是一個(gè)基于Java的日志記錄工具,是?Log4j?的升級(jí),是目前最優(yōu)秀的?Java日志框架之一,這篇文章主要介紹了突發(fā)Apache?Log4j2?報(bào)核彈級(jí)漏洞快速修復(fù)方法,需要的朋友可以參考下2021-12-12

