抽象工廠模式(Java)
工廠模式可以分為:簡單工廠模式,工廠方法模式,抽象工廠模式。
簡單工廠模式就沒什麼好說的了,無非是所有的東西都寫在一個類裡面,要什麼就呼叫什麼,如果要新增新的方法也是到這類裡面新增,程式碼很多,看起來也是很亂,就像一個大工廠,什麼都在裡面。擴充套件性很低。
而工廠方法模式,把說明的理論和生產的東西就分開一點。抽象工廠模式是工廠方法模式的升級。 說簡單點,後面兩種工廠模式都是java三大特徵的繼承和多型的具體表現,你從後面的類圖中就可以很簡單看到繼承(介面為實現)的關係,而你在程式碼中就很容易看到多型的使用。 關於工廠方法模式,上次已經有詳細的介紹了,本文主要是介紹抽象工廠模式。
抽象工廠模式的概念
抽象工廠模式的定義:為建立一組相關或相互依賴的物件提供一個介面,而且無需指定它們的具體類。 同時你也可以對比一下工廠方法模式的定義:為某個物件提供一個介面,而且無需指定它們的具體類。 都是子類實現介面的方法,並在子類寫具體的程式碼。這裡抽象工廠的介面類是能建立多個相關的物件,而工廠方法的介面類是隻建立一個物件。
抽象工廠模式的類圖:
對比工廠方法模式,你要知道它們之間的類圖區別,就能理解這兩種模式的區別。 工廠方法模式中也是可以有多個具體工廠,也是可以有多個抽象產品,和多個具體工廠、具體產品類。區別是在抽象工廠介面類中,能建立幾個產品物件。 抽象工廠模式的工廠能建立多個相關的產品物件,而工廠方法模式的工廠只建立一個產品物件。
抽象工廠模式的優點/缺點:
1.優點
針對同一組產品建立新的生產線,只需實現那組產品的抽象工廠介面即可建立新的工廠類。
2.缺點
抽象方法模式的最大缺點就是產品族本身的擴充套件非常困難。如果在產品族中增加一個新的產品型別,則需要修改多個介面,並影響現已有的工廠類。 上面這句話,有些人不怎麼理解,我給大家解釋一下,打個比方說,你要在這個工廠建立三個物件,原本只是建立兩個物件的,那麼你就要在抽象方法中新增一個建立物件的方法,那麼所有實現了這個介面的類都是要重新新增這個建立物件的方法,這就是對之前的工廠有影響的原因。
抽象工廠模式的應用場景
當一個物件都有相同的約束時,可以使用抽象工廠模式。 打個比方說,這個工廠的幾個產品都需要經過某些共同的步驟和打上相同的商標,這一組產品可以在一個工廠裡面生產,減少很多重複的程式碼在不同的地方都出現多次。
抽象工廠模式的例項
這裡設計一個工廠生產賓士汽車和它對應的導航儀兩種產品。
例項類圖
這個類圖和上面的抽象工廠的類圖是一樣的,只是把東西具體化,程式碼化。
各個介面/類的程式碼
(1)生產賓士的介面Benz
package P3_abstractFactory;
/**
* 賓士產品的抽象介面
*/
public interface Benz {
void carColor();//設定顏色
void carSpeed();//設定速度
void carPrice();//設定價格
}
(2)生產車輛導航儀的介面類
package P3_abstractFactory;
/**
* 車輛導航儀的抽象產品介面類
*/
public interface CarNavigator {
void navigatorColor();//導航儀的顏色
void navigatorPrice();//導航儀的價格
}
(3)賓士工廠的抽象介面類BanzFactory
package P3_abstractFactory;
/**
* 賓士工廠的抽象介面
*/
public interface BanzFactory {
/**
* 建立賓士的方法
*/
Benz createCar();
/**
* 建立導航儀的方法
*/
CarNavigator createNacigator();
}
(4)生產賓士車輛C180和相關導航儀的具體工廠類
package P3_abstractFactory;
/**
* 生產某一個型號賓士車輛的實際工廠
*/
public class C180Factory implements BanzFactory {
@Override
public Benz createCar() {
return new BenzC180();
}
@Override
public CarNavigator createNacigator() {
return new C180Navigator();
}
}
(5)生產賓士車輛Z260和相關導航儀的具體工廠類
package P3_abstractFactory;
/**
* 生產某一個型號賓士車E260輛的實際工廠
*/
public class E260Factory implements BanzFactory {
@Override
public Benz createCar() {
return new BenzE260();
}
@Override
public CarNavigator createNacigator() {
return new E260Navigator();
}
}
(6)生產賓士車輛C180的具體產品類
package P3_abstractFactory;
/**
* 賓士C180的生產的具體類
*/
public class BenzC180 implements Benz {
/**
* 構造方法,建立的時候就設定基本屬性
*/
public BenzC180() {
carColor();
carPrice();
carSpeed();
}
@Override
public void carColor() {
System.out.println("賓士C180的顏色是銀白色");
}
@Override
public void carSpeed() {
System.out.println("賓士C180的速度是200公里每小時");
}
@Override
public void carPrice() {
System.out.println("賓士C180的價格是100萬");
}
}
(7)生產賓士車輛C180對應導航儀的具體產品類
package P3_abstractFactory;
/**
* 車型C180的導航儀
*/
public class C180Navigator implements CarNavigator {
C180Navigator(){
navigatorColor();
navigatorPrice();
}
@Override
public void navigatorColor() {
System.out.println("汽車C180的導航儀顏色:黑色");
}
@Override
public void navigatorPrice() {
System.out.println("汽車C180的導航儀價格:480元");
}
}
賓士車輛E260的具體產品類
package P3_abstractFactory;
/**
* 賓士E260的生產的具體類
*/
public class BenzE260 implements Benz {
/**
* 構造方法,建立的時候就設定基本屬性
*/
public BenzE260() {
carColor();
carPrice();
carSpeed();
}
@Override
public void carColor() {
System.out.println("賓士E260的顏色是銀白色");
}
@Override
public void carSpeed() {
System.out.println("賓士E260的速度是200公里每小時");
}
@Override
public void carPrice() {
System.out.println("賓士E260的價格是100萬");
}
}
(7)生產賓士車輛E260對應導航儀的具體產品類
package P3_abstractFactory;
/**
* 車型E260的導航儀
*/
public class E260Navigator implements CarNavigator {
E260Navigator(){
navigatorColor();
navigatorPrice();
}
@Override
public void navigatorColor() {
System.out.println("汽車E260的導航儀顏色:白色");
}
@Override
public void navigatorPrice() {
System.out.println("汽車E260的導航儀價格:880元");
}
}
生產賓士車輛和相關產品的呼叫者類AbstractFactoryDemo
package P3_abstractFactory;
/**
* 抽象工廠模式呼叫
* 生產兩個賓士車C180、E260和它們對應的導航儀的演示
* 這裡使用多型的方法類建立各個類別的車型產品
*/
public class AbstractFactoryDemo {
public static void main(String[] a) {
System.out.println("生產賓士車C180");
//父類但物件子類的例項
BanzFactory banzFactory = new C180Factory();//建立一個C180工廠
//呼叫父類的方法,這就是java多型的一種體現
banzFactory.createCar();//C180工廠生產車輛C180
banzFactory.createNacigator();//生產車輛C180對應的導航儀
System.out.println("=========================================");
System.out.println("生產賓士車Z260");
BanzFactory banzFactory2 = new E260Factory();
banzFactory2.createCar();//E260工廠生產車輛E260
banzFactory2.createNacigator();//生產車輛E260對應的導航儀
}
}
程式執行的結果:
從例項中分析,工廠方法模式的優點/缺點
1.優點
如果需要生產新的汽車產品和對應的導航儀裝置,你只需要建立一個該產品對應的具體工廠和該產品的具體實現類,不需要改變抽象的工廠類和抽象的產品類,具體工廠類和具體產品類需要什麼操作已經在抽象介面類定義好了。
2.缺點
之前有說工廠方法的擴充套件性算是比較好的,而抽象工廠模式的擴充套件性就沒那麼好了。 比如說某個工廠需要多建立幾個產品物件,那麼就需要增加抽象工廠的方法,增加抽象介面的方法後,其他實現了抽象工廠介面方法的所有類都需要改變,才能正常編譯。
比如:我們在程式碼中有定義生產導航儀的介面方法和具體實現,那如果我們新增一個新的產品,比如內建空調,這時候要在抽象介面中新增定義生產空調的介面,並且之前所有的產品類都實現的這個介面,所以之前型號的汽車也要實現內建空調的方法,這裡方法可以是沒有具體操作的,但是方法肯定是要實現的。
https://blog.csdn.net/wenzhi20102321/article/details/78153437?utm_source=copy