[英]How to get rid of instanceof?
有人告诉我,在下面的代码中使用 instanceof 是不好的做法,因为它变得重复并且难以扩展。 我对 Java 还是很陌生,但并没有立即看到我的替代方案是什么,你会建议我做些什么来摆脱实例和抽象代码?
void moveit(Vehicle car) {
if(car instanceof Volvo240){
volvoPoint.x = (int) car.getXCoordinate();
volvoPoint.y = (int) car.getYCoordinate();
}
if(car instanceof Scania) {
scaniaPoint.x = (int) car.getXCoordinate();
scaniaPoint.y = (int) car.getYCoordinate() + 100;
}
if(car instanceof Saab95) {
saabPoint.x = (int) car.getXCoordinate();
saabPoint.y = (int) car.getYCoordinate() + 200;
}
repaint();
}
InstanceOf 将使推出新型汽车变得困难。 您将必须找到您进行这些实例检查并使用新车进行修改的所有位置。 参见“开放扩展,封闭修改”原则。
你应该有一个界面
interface Vehicle {
Integer getXCoordinate();
Integer getYCoordinate();
void moveIt(Point point);
}
以及三种实现方式,Saab95、Volvo240 和 Scania
class Saab95 implements Vehicle {
moveIt(Point point) {
point.x = getXCoordinate();
point.y= getYCoordinate() + 200
}
}
其他车以此类推
在不知道完整代码的情况下,并假设您只有这三个子类。 侵入性最小的方法是利用方法重载:
void moveit(Volvo240 car){
volvoPoint.x = (int) car.getXCoordinate();
volvoPoint.y = (int) car.getYCoordinate();
repaint();
}
void moveit(Scania car){
volvoPoint.x = (int) car.getXCoordinate();
volvoPoint.y = (int) car.getYCoordinate() + 100;
repaint();
}
void moveit(Saab95 car){
saabPoint.x = (int) car.getXCoordinate();
saabPoint.y = (int) car.getYCoordinate() + 200;
repaint();
}
void moveit(Vehicle car){
repaint();
}
在我看来,变量volvoPoint.x
和volvoPoint.y
应该属于 class Volvo240
(同样适用于其他变量)。 但是您将这些变量(应该属于Volvo240
、 Scania
和Saab95
类)保存在一个地方,以便(我假设)您可以根据这些变量的值repaint
。
您应该考虑另一种方法,在这种方法中,您教Vehicle
如何repaint
自己。 因此,将repaint
逻辑和那些变量移动到每个子类,相应地:
public class Volvo240 extends Vehicle{
public repaint(){
volvoPoint.x = (int) car.getXCoordinate();
volvoPoint.y = (int) car.getYCoordinate();
// do the repaint logic
}
}
我要直接说,我对您的原始解决方案没有任何问题。 更多关于这篇文章底部的内容。 如果您真的希望您当前的代码在不使用instanceof
的情况下工作,这是一种方法。
您可以创建一个新的 class 来存储与每种类型的车辆相关的信息,如下所示:
public class VehicleInfo {
private final Point point;
private final int offset;
public VehicleInfo(Point point, int offset) {
this.point = point;
this.offset = offset;
}
public Point getPoint() {
return point;
}
public int getOffset() {
return offset;
}
}
然后,您可以在您的方法中使用该 class ,如下所示:
private static final HashMap<Type, Point> POINT_MAP = new HashMap<Type, Point>() {
{
put(Volvo240.class, new VehicleInfo(volvoPoint, 0));
put(Scania.class, new VehicleInfo(scaniaPoint, 100));
put(Saab95.class, new VehicleInfo(saabPoint, 200));
}
};
void moveit(Vehicle car) {
VehicleInfo info = POINT_MAP.get(car.getClass());
info.getPoint().x = car.getXCoordinate();
info.getPoint().y = car.getYCoordinate() + info.getOffset();
repaint();
}
也就是说,我真的对您使用instanceof
的原始解决方案没有任何问题。 该程序将不得不在某个时候检查参数的类型,因此不妨在您的代码中明确显示这一点。 除非程序的这一部分将被反复修改,并且这是一个每个人都需要使用标准编码约定的大型项目的一部分,否则我会坚持你所拥有的,尽管这里的其他人都在说。 我最近被介绍了YAGNI的概念,我认为这绝对适用于此。 如果它有效,它就有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.