Reducing coupling from switch statement

129 Views Asked by At
private void initialiseVehicle(String vehicleName) {
    
    if (vehicleName == null) {
    } else {
        switch (vehicleName) {
        case "Boat":
            vehicle = new Boat("Apollo ");
            break;
        case "Ship":
            vehicle = new Ship("Cruizz");
            break;
        case "Truck":
            vehicle = new Truck("Ford F-650");
            break;
        case "Motorcycle":
            vehicle = new Motorcycle("Suzuki");
            break;
        case "Bus":
            vehicle = new Bus("Aero");
            break;
        case "Car":
            vehicle = new Car("BMW");
            break;
        case "Bicycle":
            vehicle = new Bicycle("A-bike");
            break;
        case "Helicopter":
            vehicle = new Helicopter("Eurocopter");
            break;
        case "Airplane":
            vehicle = new Airplane("BA");
            break;
        case "Tram":
            vehicle = new Tram("EdinburghTram");
            break;
        case "Train":
            vehicle = new Train("Virgin",4);
            break;
        }
    }

    
}

I have edited this from an if-else statement to a switch, but I have tried to reduce the CBO metric by doing this and was wondering if there was any way to reduce the coupling here and I can provide more information if needed.

2

There are 2 best solutions below

2
AudioBubble On

switch expression (not that different):

vehicle = switch (name) {
    case "Boat" -> new Boat("Apollo ");
    case "Ship"-> new Ship("Cruizz");
    case "Truck"-> new Truck("Ford F-650");
    ...
}

A Map from name to Supplier:

final Map<String, Supplier<Vehicle>> supplierMap;
...
supplierMap.put("Boat", () -> new Boat("Apollo "));
supplierMap.put("Ship", () -> new Ship("Cruizz"));
supplierMap.put("Truck", () -> new Truck("Ford F-650"));
...
vehicle = supplierMap.get(name).get();

A Map from name to template (just an idea):

final Map<String, Vehicle> supplierMap;
...
supplierMap.put("Boat", new Boat("Apollo "));
supplierMap.put("Ship", new Ship("Cruizz"));
supplierMap.put("Truck", new Truck("Ford F-650"));
...
vehicle = supplierMap.get(name).clone();

Register the vehicle-providing classes as service, using for example the ServiceLoader framework


just some ideas
(there are eventually better ways to populate a map) e.g. each object register itself to the map

0
ChinmayH On

Not sure what you exactly mean by reducing coupling between objects, but your problem seems creational in behavior and hence using one of the creational design patterns, named Factory Design Pattern, seems like a wise choice to me.

For your situation you can create an interface named 'Vehicle'. And then create classes for every switch case like Boat, Ship, Truck and so on. These concrete classes will implement interface Vehicle. Interface can have unimplemented method like move() and concrete classes will provide custom implementation in them for such methods like sailing, cruising, paddling, flying etc.

This way they will be least coupled and independent of each other.

To know more about Factory Design Pattern, check this: https://refactoring.guru/design-patterns/factory-method Factory Method/Factory Design Pattern