使用java实现工厂方法模式

文章介绍了如何使用工厂方法模式解决简单工厂模式在扩展时违反开闭原则的问题。通过创建抽象工厂类和具体工厂类,实现了在不修改已有代码的情况下增加新的交通工具类型(如宇宙飞船)。客户端使用反射调用工厂创建对象,使得系统更具扩展性。
摘要由CSDN通过智能技术生成

在简单工厂模式中,我们使用了Factory来创建对象,让调用者无需关心对象的创建细节,只需要输入想要的字符串就能获取到对应的对象。但是后续如果新增了一个Ship类,维护者需要去修改工厂类,去添加一个判断,这样非常麻烦,违背了开闭原则,一般来说,写好了的代码,我们都不希望去动他们了。那么有没有办法能够不动之前的代码前提下,新增一个Ship类,让调用者能够正常调用。

下面我们将使用工厂方法模式来实现这个需求。

1-交通工具类不变

abstract public class Vehicle {
    //公共抽象方法
    public abstract String getName();
}

public class Plane extends Vehicle {
    private String name;
    public Plane(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}

public class Car extends Vehicle {
    private String name;
    public Car(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}

2-新增一个抽象的工厂类Factory,并且将创建交通工具类的实现分别交给BenzFactory和BoeingFactory。

public abstract class Factory {
    
    public abstract Vehicle buildVehicle();
}

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

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

3-在客户端调用时使用反射调用工厂创建交通工具类

    @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");
            Factory o = (Factory) Class.forName(map.get(code)).newInstance();
            Vehicle vehicle = o.buildVehicle();
            System.out.println(vehicle.getName());
        }
    }

4-完成了工厂方法模式改造之后,后续拓展就不用修改以前的代码了。如果我们新增了一个需求,客户需要一艘宇宙飞船,我们不用修改之前的代码也能实现这个需求。

4-1我们先来一个宇宙飞船类Ship并且继承Vehicle,再来一个SpaceXFactory类继承Factory。

public class Ship extends Vehicle{
    private String name;
    public Ship(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}

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

4-2然后在客户端浅浅的加一段映射,就能直接创建宇宙飞船了。

map.put("ship","com.SpaceXFactory");

5-不用改之前的代码,可以说是非常方便维护的人员了,不然在造宇宙飞船的时候,改了一行造汽车的代码,然后报错了。我就还得去学习造汽车来修复这个问题。非常耽误我造宇宙飞船的时间。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值