使用java实现抽象工厂方法模式

80 阅读2分钟

在工厂方法模式当中,我们坐拥奔驰、波音、SpaceX三大工厂,分别生产奔驰汽车、波音飞机、猎鹰火箭三大顶级产品。但是这三种东西都太贵了,普通人都买不起,现在,三大公司的联合CEO为了推出新的业务(割韭菜),决定推出模型手办业务来拓展公司的商业版图。你作为三大公司的联合CEO帐下的首席软件开发工程师的助理下的实习生,要怎么实现该业务呢?

1-新增一个抽象产品类Model和三个具体产品类CarModel、PlaneModel、RocketModel

public abstract class Model {

    //抽象产品——模型
    public abstract String getModel();
}

public class CarModel extends Model {
    private String name;

    public CarModel(String name) {
        this.name = name;
    }

    @Override
    public String getModel() {
        return name;
    }
}

public class PlaneModel extends Model {
    private String name;

    public PlaneModel(String name) {
        this.name = name;
    }

    @Override
    public String getModel() {
        return name;
    }
}

public class RocketModel extends Model {
    private String name;

    public RocketModel(String name) {
        this.name = name;
    }

    @Override
    public String getModel() {
        return name;
    }
}

2-在抽象工厂中新增一个抽象方法buildModle(),并且在BenzFactory、BoeingFactory和SpaceFactory中实现该方法。如下代码:

public abstract class Factory {
    /**
     * 建造交通工具的抽象方法
     * @return
     */
    public abstract Vehicle buildVehicle();

    /**
     * 建造模型手办的抽象方法
     * @return
     */
    public abstract Model buildModel();
}


public class BenzFactory extends Factory {
    @Override
    public Vehicle buildVehicle() {
        return new Car("奔驰");
    }

    @Override
    public Model buildModel() {
        return new CarModel("奔驰模型");
    }
}

public class BoeingFactory extends Factory {
    @Override
    public Vehicle buildVehicle() {
        return new Plane("波音");
    }

    @Override
    public Model buildModel() {
        return new PlaneModel("波音飞机模型");
    }
}

public class SpaceXFactory extends Factory {
    @Override
    public Vehicle buildVehicle() {
        return new Ship("宇宙飞船");
    }

    @Override
    public Model buildModel() {
        return new RocketModel("火箭模型");
    }
}

3-直接调用factory.buildModel就可以了,其他的不用动

    @SneakyThrows
    public static void main(String[] args) {
        while (true){
            Scanner scanner = new Scanner(System.in);
            String code = scanner.nextLine();
            //新增一个map用来映射调用代号和创建路径
            Map<String, String> map = new HashMap<>();
            map.put("car","com.BenzFactory");
            map.put("plane","com.BoeingFactory");
            map.put("ship","com.SpaceXFactory");

            Factory factory = (Factory) Class.forName(map.get(code)).newInstance();
            Vehicle vehicle = factory.buildVehicle();
            System.out.println("vehicle="+vehicle.getName());

            //新增建造模型的方法
            Model model = factory.buildModel();
            System.out.println("model="+model.getModel());

        }
    }

​编辑

总结一下:抽象工厂方法的本质是工厂方法的拓展,我们在工厂方法原有的基础改就行了。客户端调用的时候直接调用新的工厂方法创建新的产品就好了。使用抽象工厂方法之后,以后如果有新的公司要建造交通工具和模型手办就非常方便,只需要实现Vehicle、Model、Factory就可以了,不用修改以前的代码。但是抽象工厂方法也有缺点,在我们编写代码的过程中,我们在Factory新增的buildModel方法,改动了以前的类,这样就不符合开闭原则了(不要动以前的人的代码)。所以使用抽象工厂方法模式添加已有的产品(如交通工具、模型)就非常方便,如果添加一个Factory里没有的方法,就需要改动Factory。