摘抄至https://www.jianshu.com/p/3c3f6c95d7e7
本文講解GOF-23種設計模式其中的工廠方法模式和抽象工廠模式。
由於本人愛國情懷高漲,所以本文都以長安汽車作爲示例,閱讀本文需要對長安汽車有一定了解。
長安悅翔V7:長安旗下一款性價比超高的緊湊型家用轎車,輪胎尺寸R15。
長安CS75:長安旗下一款中端緊湊型城市SUV,輪胎尺寸R17。
以上兩款車和車輪胎都是長安集團的產品,那麼生產輪胎和組裝車的地方是長安的工廠。
一. 簡單工廠模式
1、簡介
簡單工廠模式(Simple Factory)其實不算是23種設計模式之一,只算是工廠方法模式的一種特殊寫法,是較爲常用的工廠模式(下文簡稱模式A)。
2、成員
抽象產品:它是具體產品的抽象父類 或者實現的接口。
具體產品:具體的產品類,在JAVA中是一個實現了抽象產品的類。
工廠類:生產具體產品的工廠,具有一定的業務邏輯和判斷,生產不同的具體產品。
3、使用場景
在業務簡單,對象較少且不易改動的情況下可使用此模式。
4、代碼示例
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是一個長安汽車抽象類,用[abstract]抽象類也可實現!
*/
public interface ICar {
/**
* 汽車的價格
*/
double getPrice();
/**
* 汽車的型號
*/
String getModel();
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是具體的長安汽車產品-悅翔V7,需要實現汽車接口。
*/
public class V7Info implements ICar {
@Override
public double getPrice() {
return 100000;
}
@Override
public String getModel() {
return "長安悅翔V7";
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是具體的長安汽車產品-CS75,需要實現汽車接口。
*/
public class CS75Info implements ICar {
@Override
public double getPrice() {
return 150000;
}
@Override
public String getModel() {
return "長安CS75";
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 工廠模式-簡單模式
* 解釋: 這是長安汽車的工廠,可以根據不同的需求生產不同的汽車產品。
*/
public class ICarFactory_1 {
public static final String car_type_v7 = "V7";
public static final String car_type_cs75 = "CS75";
public static ICar createCar(String carType) {
if (car_type_v7.equals(carType)) {
return new V7Info();
} else if (car_type_cs75.equals(carType)) {
return new CS75Info();
} else {
return new V7Info();
}
}
}
/**
* 測試簡單工廠模式
*/
public void TestFactory1() {
ICar car1 = ICarFactory_1.createCar(ICarFactory_1.car_type_v7);
Log.d("MainActivity", car1.getModel() + "的價格是" + car1.getPrice());
}
最終打印結果:長安悅翔V7的價格是100000.0
二、工廠方法模式
1、簡介
工廠方法模式(Factory Method),是爲解決模式A的一些缺點而生。
(下文把此模式簡稱模式B)
2、優點/區別
1、解耦:消費者與產品完全隔離,消費者依賴產品接口實現對產品的操作。
2、擴展:如果要新增汽車類型,只需增加具體汽車類和工廠即可,不用修改原工廠。
3、成員:
除了模式A裏面的【抽象產品】【具體產品】,還需新增以下成員:
抽象工廠:它是具體工廠的抽象父類/實現的接口。
具體工廠:此處的工廠也是模式A中的工廠,與模式A工廠的區別是:模式A的工廠可以根據邏輯判斷生產不同的產品,而模式B的工廠只能生產一種產品,如果需要生產多種產品則需要創建多個工廠。
4、使用場景
如果產品類型比較單一,且不能預見需要創建哪些類、創建多少類的情況下使用模式B。
5、代碼示例:(接上文的例子)
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 工廠方法模式-長安的工廠都必須遵循此協議
*/
public interface ICarFactory_2 {
ICar createCar();
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是長安其中一家工廠,此工廠只生產悅翔V7
*/
public class CarV7Factory_2 implements ICarFactory_2 {
@Override
public ICar createCar() {
return new V7Info();
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是長安另一家工廠,此工廠只生產CS75
*/
public class CarCS75Factory_2 implements ICarFactory_2 {
@Override
public ICar createCar() {
return new CS75Info();
}
}
/**
* 測試工廠方法模式
*/
public void TestFactory2() {
ICarFactory_2 factory_v7 = new CarV7Factory_2();
ICar car_v7 = factory_v7.createCar();
Log.d("MainActivity", "A:" + car_v7.getModel() + "的價格是" + car_v7.getPrice());
ICarFactory_2 factory_CS75 = new CarCS75Factory_2();
ICar car_75 = factory_CS75.createCar();
Log.d("MainActivity", "B:" + car_75.getModel() + "的價格是" + car_75.getPrice());
}
最終打印結果:
A:長安悅翔V7的價格是100000.0
B:長安CS75的價格是150000.0
三、抽象工廠模式
1、簡介
抽象工廠模式(Abstract Factory)是模式B的更爲抽象的寫法,成員與模式B相同,就不具體列舉了(以下簡稱模式C)。
2、代碼示例(繼續接上文例子,注意此例子中長安集團產品族中增加了新的產品:輪胎)
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是長安輪胎產品協議,用[abstract]抽象類也可實現!
*/
public interface ITyre {
/**
* 輪胎尺寸
*/
String getSize();
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 長安悅翔V7的輪胎
*/
public class V7TyreInfo implements ITyre {
@Override
public String getSize() {
return "R15";
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 長安CS75的輪胎
*/
public class CS75TyreInfo implements ITyre {
@Override
public String getSize() {
return "R17";
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 抽象工廠模式
* 解釋: 長安新增了產品,那麼工廠的協議就要改變了,既要生產汽車也要生產輪胎
*/
public interface ICarFactory_3 {
/**
* 生產汽車
*/
ICar createCar();
/**
* 生產輪胎
*/
ITyre createTyre();
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是長安其中一家工廠,此工廠原來只生產悅翔V7,現在新增了輪胎生產線
*/
public class CarV7Factiry_3 implements ICarFactory_3 {
@Override
public ICar createCar() {
return new V7Info();
}
@Override
public ITyre createTyre() {
return new V7TyreInfo();
}
}
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 這是長安另一家工廠,此工廠原來只生產CS75,現在新增了CS75輪胎的生產線
*/
public class CarCS75Factory_3 implements ICarFactory_3 {
@Override
public ICar createCar() {
return new CS75Info();
}
@Override
public ITyre createTyre() {
return new CS75TyreInfo();
}
}
/**
* 測試抽象工廠模式
*/
public void TestFactoiry3() {
ICarFactory_3 factory_v7 = new CarV7Factiry_3();
ICar carV7 = factory_v7.createCar();
ITyre tyrev7 = factory_v7.createTyre();
Log.d("MainActivity", "C:" + carV7.getModel() + "的價格是" + carV7.getPrice() + ",輪胎尺寸是" + tyrev7.getSize());
ICarFactory_3 factory_75 = new CarCS75Factory_3();
ICar car75 = factory_75.createCar();
ITyre tyre75 = factory_75.createTyre();
Log.d("MainActivity", "C:" + car75.getModel() + "的價格是" + car75.getPrice() + ",輪胎尺寸是" + tyre75.getSize());
}
最終打印結果:
C:長安悅翔V7的價格是100000.0,輪胎尺寸是R15
C:長安CS75的價格是150000.0,輪胎尺寸是R17