【发布时间】:2021-03-07 06:27:50
【问题描述】:
我正在尝试使用面向对象的方法设计一个停车场系统。停车场可以有多种类型的停车位,如残疾人、紧凑型、大型、摩托车等。
最初,我正在考虑创建一个枚举来对这些不同类型进行建模,如下所示:
public enum ParkingSpotType {
HANDICAPPED,
COMPACT,
LARGE,
MOTORBIKE
}
然后,在ParkingSpot 类中使用它们,如下所示:
public abstract class ParkingSpot {
private ParkingSpotType type;
}
同样,Vehicle 类也将具有 VehicleType,它将映射到停车所需的 ParkingSpotType
public class Vehicle {
private VehicleType vehicleType;
// other fields
}
public enum VehicleType {
CAR (ParkingSpotType.COMPACT),
BUS (ParkingSpotType.LARGE),
TRUCK (ParkingSpotType.LARGE),
BIKE (ParkingSpotType.MOTORBIKE),
CYCLE (ParkingSpotType.MOTORBIKE);
private ParkingSpotType parkingSpotType;
VehicleType(ParkingSpotType parkingSpotType) {
this.parkingSpotType = parkingSpotType;
}
}
这使我能够通过以下操作从Vehicle 中找到ParkingSpotType:
vehicle.getVehicleType().getParkingSpotType()
但是,有人告诉我,这会违反 Open/Closed 设计原则。任何添加新类型都可能需要在现有的各个地方更改代码,这将违反开放/封闭设计原则,即在需要引入新功能时不应修改现有和经过良好测试的类。有人建议我为不同的类型创建不同的子类如下:
public class HandicappedSpot extends ParkingSpot {
}
public class CompactSpot extends ParkingSpot {
}
public class LargeSpot extends ParkingSpot {
}
public class MotorbikeSpot extends ParkingSpot {
}
但是使用这种方法,如果我没有相同的枚举建模,我将如何将 Vehicle 映射到 ParkingSpot。如果第一种方法确实对OO-Design不好,有人可以看看并发表评论。如果是,我将如何解决第二种方法中的上述问题?
【问题讨论】:
-
这取决于您对停车位的预期差异。如果您需要问他们的唯一问题是“这里有什么样的车?”,答案是一种车,那么枚举就更合适了。但是,如果您计划制作仅适用于特定类型停车位的功能(也许您有一个具有特殊“加油车”功能的
ElectricCarSpot),那么这些应该是子类,因为它们添加了功能。 -
不要为了添加子类而添加子类;只有在添加功能时才扩展一个类。即使你是,也值得问是否有比直接实现继承更好的方法,坦率地说,这很少是答案。考虑组合(一个残障点“包含”一个普通停车位,我们可以从中查询普通停车位属性),或者在您的情况下更有可能用一个接口替换
ParkingSpot并让几个类扩展它。接口继承是实现继承更常见、危害更小的表亲。
标签: java oop object-oriented-analysis