以汽車工廠為例,首先有個汽車類的介面 Car,裡面有個開車的方法 drive(),然後有個寶馬車的類 BMW 和賓士車的類 Benz 實現了 Car 介面。 public interface Car{ public void drive(); } public class BMW implement ...
以汽車工廠為例,首先有個汽車類的介面 Car,裡面有個開車的方法 drive(),然後有個寶馬車的類 BMW 和賓士車的類 Benz 實現了 Car 介面。

public interface Car{ public void drive(); } public class BMW implements Car{ public BMW(){ System.out.println("生產一臺寶馬車"); } public void drive(){ System.out.println("我開寶馬車"); } } public class Benz implements Car{ public Benz(){ System.out.println("生產一臺賓士車"); } public void drive(){ System.out.println("我開賓士車"); } }View Code
現在如果要用 BMW 這個類,最基本的方法是:BMW bmw = new BMW(); 如果還要個 Benz 類,就得:new Benz();
這樣每個都得 new 個汽車對象,但是寶馬和賓士都屬於汽車,都有 drive() 方法;那我們是不是能創建一個生產汽車的工廠,
然後想要什麼汽車告訴工廠,工廠幫你生產就可以了,而不用管生產的細節(也就是 new 對象的過程),這樣會更好呢?
到此,簡單工廠模式就出來了。
一. 簡單工廠模式

public class CarFactory{ public static Car createCar(String carName){ if("BMW".equals(carName)){ return new BMW(); }else if("Benz".equals(carName)){ return new Benz(); } } }View Code
如果要生產一臺汽車,直接調用 Car car = CarFactory.createCar("BMW"); 就可以了。
這種工廠雖然挺好,但是每次要加入新車都得修改工廠類來加入新的判斷語句,不符合開閉原則;
所以又有了一種更好的生產方式,這就是工廠方法模式。
二. 工廠方法模式
首先抽象出一個生產汽車的工廠類介面,然後讓具體工廠類實現這個介面,這樣就有寶馬車生產工廠、賓士車生產工廠。

public interface CarFactory{ public static Car createCar(); } public class BMWFactory implements CarFactory{ public static Car createCar(){ return new BMW(); } } public class BenzFactory implements CarFactory{ public static Car createCar(){ return new Benz(); } }View Code
這樣的好處就是如果我還要生產長城汽車,不用去修改 CarFactory 工廠,只要寫個長城工廠類去實現CarFactory介面就可以了。
隨著社會的進步,汽車種類也多了,比如分為越野車和跑車兩個系列,這樣原來 Car 介面就不能通用,
而變成 YueYeChe 和 PaoChe 兩個介面,而越野車適合在山上跑,跑車適合在賽路上跑,drive 的方法也改變了,如下:

public interface YueYeChe{ public void driveShanLu(); } public interface PaoChe{ public void driveSaiLu(); }View Code
而寶馬和賓士都生產跑車和越野車:

public BMWYueYeChe implements YueYeChe{ public void driveYueYeChe(){ System.out.println("我在山路上開寶馬越野車"); } } public BMWPaoChe implements PaoChe{ public void drivePaoChe(){ System.out.println("我在賽路上開寶馬跑車"); } } public BenzYueYeChe implements YueYeChe{ public void driveYueYeChe(){ System.out.println("我在山路上開賓士越野車"); } } public BenzPaoChe implements PaoChe{ public void drivePaoChe(){ System.out.println("我在賽路上開賓士跑車"); } }View Code
按照工廠方法模式,我們需要 YueYeCheFactory 和 PaoCheFactory 兩個工廠介面,以及 BMWYueYeCheFactory 、
BMWPaoCheFactory、BenzYueYeCheFactory 、BenzPaoCheFactory 四個具體工廠類。如果需要再生產其他車,工廠類
會呈指數增長,難以維護。如果能對工廠介面進行擴充,不是更好?這樣就產生了抽象工廠模式。
三. 抽象工廠模式
工廠方法模式一般是針對一種系列的抽象產品的生產,為變成可以對多種系列的產品進行生產,而把工廠方法模式進行擴充,
這就是抽象工廠模式。因為 Car 類分成了跑車和越野車,所以擴充後的工廠介面也就能生產出跑車和越野車。這樣,寶馬工廠類
可以生產寶馬跑車和寶馬越野車,賓士工廠類可以生產賓士跑車和賓士越野車。

public interface CarFactory{ public static PaoChe createPaoChe(); public static YueYeChe createYueYeChe(); } public BMWFactory implements CarFactory{ public static PaoChe createPaoChe(){ return new BMWPaoChe(); } public static YueYeChe createYueYeChe(){ return new BMWYueYeChe(); } } public BenzFactory implements CarFactory{ public static PaoChe createPaoChe(){ return new BenzPaoChe(); } public static YueYeChe createYueYeChe(){ return new BenzYueYeChe(); } }View Code