设计模式 - 抽象工厂模式

99 阅读2分钟

工厂模式(简单工厂模式、工厂方法模式)与抽象工厂模式的区别:

  1. 工厂模式偏向于生产一个产品,抽象工厂模式更偏向于生产一条产品簇
  2. 比如工厂模式生产(保时捷的轮胎、保时捷的电子系统、保时捷的xxx)
  3. 抽象工厂模式生产 3.1 保时捷的轮胎、法拉利的轮胎、xxx的轮胎 3.2 保时捷的电子系统、法拉利的电子系统、xxx的电子系统

抽象工厂模式流程图如下

image.png

代码文件如下图

image.png

车子组装的子路线

public interface CarMake {
    void makeTire();
    void makeWindow();
    void makeLight();
    void makeTrumpet();
}
public class PorscheCarMake implements CarMake {
    @Override
    public void makeTire() {
        System.err.println("保时捷组装轮子");
    }

    @Override
    public void makeWindow() {
        System.err.println("保时捷组装车窗");
    }

    @Override
    public void makeLight() {
        System.err.println("保时捷组装大灯");
    }

    @Override
    public void makeTrumpet() {
        System.err.println("保时捷组装喇叭");
    }
}
public class FerrariCarMake implements CarMake {
    @Override
    public void makeTire() {
        System.err.println("法拉利组装轮子");
    }

    @Override
    public void makeWindow() {
        System.err.println("法拉利组装车窗");
    }

    @Override
    public void makeLight() {
        System.err.println("法拉利组装大灯");
    }

    @Override
    public void makeTrumpet() {
        System.err.println("法拉利组装喇叭");
    }
}

车子电子的子路线

public interface CarElectronic {
    void electronicMap();
    void electronicVoice();
    void electronicWarning();
    void electronicListener();
}
public class PorscheCarElectronic implements CarElectronic {
    @Override
    public void electronicMap() {
        System.err.println("保时捷电子地图");
    }

    @Override
    public void electronicVoice() {
        System.err.println("保时捷电子语音");
    }

    @Override
    public void electronicWarning() {
        System.err.println("保时捷电子警报");
    }

    @Override
    public void electronicListener() {
        System.err.println("保时捷电子监视");
    }
}
public class FerrariCarElectronic implements CarElectronic {
    @Override
    public void electronicMap() {
        System.err.println("法拉利电子地图");
    }

    @Override
    public void electronicVoice() {
        System.err.println("法拉利电子语音");
    }

    @Override
    public void electronicWarning() {
        System.err.println("法拉利电子警报");
    }

    @Override
    public void electronicListener() {
        System.err.println("法拉利电子监视");
    }
}

车工厂的总路线

/**
 * 抽象工厂模式
 */
public interface CarFactory {
    // 车组装
    CarMake CarMake();

    // 车电子
    CarElectronic CarElectronic();
}
public class PorscheFactory implements CarFactory {

    @Override
    public CarMake CarMake() {
        return new PorscheCarMake();
    }

    @Override
    public CarElectronic CarElectronic() {
        return new PorscheCarElectronic();
    }
}
public class FerrariFactory implements CarFactory {
    @Override
    public CarMake CarMake() {
        return new FerrariCarMake();
    }

    @Override
    public CarElectronic CarElectronic() {
        return new FerrariCarElectronic();
    }
}

最终客户买车

public class Customer {
    public static void main(String[] args) {
        System.err.println("===========保时捷==========");
        PorscheFactory porscheFactory = new PorscheFactory();

        CarMake porscheCarMake = porscheFactory.CarMake();
        porscheCarMake.makeTire();
        porscheCarMake.makeWindow();
        porscheCarMake.makeLight();
        porscheCarMake.makeTrumpet();

        CarElectronic porscheCarElectronic = porscheFactory.CarElectronic();
        porscheCarElectronic.electronicMap();
        porscheCarElectronic.electronicVoice();
        porscheCarElectronic.electronicWarning();
        porscheCarElectronic.electronicListener();


        System.err.println("===========法拉利==========");
        FerrariFactory ferrariFactory = new FerrariFactory();

        CarMake ferrariCarMake = ferrariFactory.CarMake();
        ferrariCarMake.makeTire();
        ferrariCarMake.makeWindow();
        ferrariCarMake.makeLight();
        ferrariCarMake.makeTrumpet();

        CarElectronic ferrariCarElectronic = ferrariFactory.CarElectronic();
        ferrariCarElectronic.electronicMap();
        ferrariCarElectronic.electronicVoice();
        ferrariCarElectronic.electronicWarning();
        ferrariCarElectronic.electronicListener();
    }
}

UML类图

image.png

分析利弊

如果需要让车工厂做更多的事,比如 在车工厂内再加一个涂鸦路线

/**
 * 抽象工厂模式
 */
public interface CarFactory {
    // 车组装
    CarMake CarMake();

    // 车电子
    CarElectronic CarElectronic();
    
    // 车涂鸦
    CarPaint CarPaint();
}

势必影响到其他的产品路线,如法拉利、保时捷路线,也需要去新增涂鸦的功能,这个改动违背了开闭原则。因此如果功能是很稳定的,那么抽象工厂模式的价值极高,如果是不稳定的,建议不使用抽象工厂模式。

参考资料 image.png

image.png

image.png