比较父类型的两个子项时的正确API实现

时间:2013-12-08 01:27:56

标签: java oop design-patterns inheritance instanceof

鉴于以下内容:

public interface Vehicle {
    // Makes this vehicle race another Vehicle and returns who wins the race.
    public Vehicle race(Vehicle otherVehicle);
}

public class Car implements Vehicle {
    @Override
    public Vehicle race(Vehicle otherVehicle) {
        // Different algorithms are used to determine who wins based on
        // what type otherVehicle is.
        if(otherVehicle instanceof Car) {
            // Use algorithm #1 to determine who wins the race
        } else if(otherVehicle instanceof Helicopter) {
            // Use algorithm #2 to determine who wins the race
        } else if(otherVehicle instanceof Motorcycle) {
            // Use algorithm #3 to determine who wins the race
        }

        // ...etc.
    }
}

public class Helicopter implement Vehicle {
    @Override
    public Vehicle race(Vehicle otherVehicle) {
        // Same problem as above with Car.
    }
}

public class Motorcycle implements Vehicle {
    // ... same problem here
}

... lots of other types of Vehicles

由于使用了不同的算法来竞争CarCarCarHelicopter等竞争,race(Vehicle)方法的实施变得不雅观,满满的instanceof检查...哎呀。

必须是更多OO方式这样做...想法?

1 个答案:

答案 0 :(得分:1)

您可以使用double dispatch模式:

public interface Vehicle {
    // Makes this vehicle race another Vehicle and returns who wins the race.
    public Vehicle race(Vehicle otherVehicle);
    public Vehicle race(Helicopter otherVehicle);
    public Vehicle race(Motorcycle otherVehicle);
    public Vehicle race(Car otherVehicle);
}

public class Helicopter implement Vehicle {
    @Override
    public Vehicle race(Vehicle otherVehicle) {
        otherVehicle.race(this);
    }

    public Vehicle race(Helicopter heli) {

    }
    ...
}

public class Car implement Vehicle {
    @Override
    public Vehicle race(Vehicle otherVehicle) {
        otherVehicle.race(this);
    }

    public Vehicle race(Helicopter heli) {
        return heli;
    }
    ...
}


public static void Main(string args[]) {
    Vehicle car = new Car();
    Vehicle helicopter = new Helicopter();

    Vehicle winner = helicopter.race(car);
    // returns helicopter
}