工廠的進化

本文從一個簡單示例的需求不斷衍化過程,來分析理解簡單工廠,工廠方法,抽象工廠模式。

首先看一下初始示例

public interface Car {

    public void drive();
}

public class BenzCar implements Car {

    @Override
    public void drive() {
        System.out.println("Benz Car drived on the way!");
    }
}

public class BmwCar implements Car{

    @Override
    public void drive() {
        System.out.println("Bmw car drived on the way!");
    }
}

public class PorscheCar implements Car {

    @Override
    public void drive() {
        System.out.println("Porsche car drived on the way!");
    }
}

public class Client {

    public static void main(String[] args){
        Car car;
        car = new BenzCar();
        car.drive();

        car = new BmwCar();
        car.drive();
    }
}

客戶端與具體的Car實現類耦合,我們想到優化的第一步是把獲得汽車的工作轉移到工廠類,使用簡單工廠把生產Car的邏輯做一層封裝實現解耦,於是有了下面的代碼
SimpleFactory

public class SimpleCarFactory {

    public Car createCar(String car){
        Car newCar = null;
        if("Benz".equals(car)){
            newCar = new BenzCar();
        }else if("Bmw".equals(car)){
            newCar = new BmwCar();
        }else if("Porsche".equals(car)){
            newCar = new PorscheCar();
        }else {
            throw new RuntimeException("Car brand Invalid!");
        }

        return newCar;
    }
}

public class Client {

    public static void main(String[] args){

        Car car = new SimpleCarFactory().createCar("Benz");

        if(car != null){
            car.drive();
        }

    }
}

Client類看起來清晰了很多,需要汽車直接從工廠獲取就可以,但隨後我們想到這樣一個問題,隨着以後car品牌的增多,我們需要不斷在SimpleCarFactory中增加if…else…代碼,違背了OO的對擴展開放,對修改關閉的原則,於是我們想到了工廠方法,對工廠的變化實現解耦。
FactoryMethod

public interface CarFactory {

    public Car createCar() throws Exception;

}

public class BenzCarFactory implements CarFactory {

    @Override
    public Car createCar() throws Exception {
        return new BenzCar();
    }
}

public class BmwCarFactory implements CarFactory {

    @Override
    public Car createCar() throws Exception {
        return new BmwCar();
    }
}

public class PorscheCarFactory implements CarFactory {

    @Override
    public Car createCar() throws Exception {
        return new PorscheCar();
    }
}

public class VolvoCarFactory implements CarFactory{

    @Override
    public Car createCar() throws Exception {
        return new VolvoCar();
    }
}

public class Client {

    public static void main(String[] args) throws Exception{
        CarFactory carFactory = null;
        Car car = null;

        carFactory = new BenzCarFactory();
        car = carFactory.createCar();
        car.drive();

        carFactory = new VolvoCarFactory();
        car = carFactory.createCar();
        car.drive();
    }
}

工廠方法實現後,我們增加了VolvoCar,只需要增加VolvoCarFactory的工廠生產VolvoCar,就可以在客戶端直接調用,非常方便。

But,隨着業務的日漸複雜,所有的汽車品牌都發展出了不同功能的汽車,如跑車,商務車,越野車,客戶如果需要Benz的跑車,這個時候工廠該怎麼處理呢?
分析需求可以理解:車的類型基本變動不大,主要是品牌的不斷增加,比如之後會有大衆,奧迪等品牌的加入。
因此,可以考慮在工廠方法的基礎上,把工廠進行一層抽象,於是有了下面的抽象工廠的實現。
AbstractFactory

public class BenzBusinessCar extends BenzCar {

    @Override
    public void drive() {
        System.out.println("Benz Business Car drived on the way!");
    }
}

public class BenzSportCar extends BenzCar {

    @Override
    public void drive() {
        System.out.println("Benz Sport Car drived on the way!");
    }
}

public class BenzSUVCar extends BenzCar {

    @Override
    public void drive() {
        System.out.println("Benz SUV Car drived on the way!");
    }
}

public class BmwBusinessCar extends BmwCar {

    @Override
    public void drive() {
        System.out.println("Bmw Business Car drived on the way!");
    }
}

public class BmwSportCar extends BmwCar {

    @Override
    public void drive() {
        System.out.println("Bmw Sport car drived on the way!");
    }
}

public class BmwSUVCar extends BmwCar {

    @Override
    public void drive() {
        System.out.println("Bmw SUV car drived on the way!");
    }
}

public class PorscheBusinessCar extends PorscheCar {

    @Override
    public void drive() {
        System.out.println("Porsche Business car drived on the way!");
    }
}

public class PorscheSportCar extends PorscheCar {

    @Override
    public void drive() {
        System.out.println("Porsche Sport car drived on the way!");
    }
}

public class PorscheSUVCar extends PorscheCar {

    @Override
    public void drive() {
        System.out.println("Porsche SUV car drived on the way!");
    }
}

public interface CarFactory {

    Car createBusinessCar();

    Car createSUVCar();

    Car createSportCar();
}

public class BenzCarFactory implements CarFactory{

    @Override
    public BenzCar createBusinessCar() {
        return new BenzBusinessCar();
    }

    @Override
    public BenzCar createSUVCar() {
        return new BenzSUVCar();
    }

    @Override
    public BenzCar createSportCar() {
        return new BenzSportCar();
    }
}

public class BmwCarFactory implements CarFactory {

    @Override
    public BmwCar createBusinessCar() {
        return new BmwBusinessCar();
    }

    @Override
    public BmwCar createSUVCar() {
        return new BmwSUVCar();
    }

    @Override
    public BmwCar createSportCar() {
        return new BmwSportCar();
    }
}

public class PorscheCarFactory implements CarFactory {

    @Override
    public PorscheCar createBusinessCar() {
        return new PorscheBusinessCar();
    }

    @Override
    public PorscheCar createSUVCar() {
        return new PorscheSUVCar();
    }

    @Override
    public PorscheCar createSportCar() {
        return new PorscheSportCar();
    }
}

public class Client {

    public static void main(String[] args){
        createCarAndDrive(new BenzCarFactory());
        createCarAndDrive(new PorscheCarFactory());
    }

    public static void createCarAndDrive(CarFactory carFactory){
        Car businessCar = carFactory.createBusinessCar();
        businessCar.drive();

        Car sportCar = carFactory.createSportCar();
        sportCar.drive();

        Car suvCar = carFactory.createSUVCar();
        suvCar.drive();
    }
}

這樣客戶獲得一輛想要的車就很方便,只要確定哪個品牌,獲得對應品牌的工廠,然後從工廠裏獲得想要的類型的車就可以了。

似乎一切都很順利
但隨着業務的不斷複雜,需要增加幾種車的類型呢,比如說增加輕便的兩座車,長10m的貴賓車,對於目前抽象工廠,貌似改動會非常大,這種情況有如何方便地擴展呢?
留做思考,後續解答!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章