Java 停车场OO设计-枚举是否违反开放/关闭原则?
我正在尝试使用面向对象的方法设计一个停车场系统。停车场可设置残疾人、小型、大型、摩托车等多种停车位 最初,我考虑创建一个枚举来对这些不同类型进行建模,如下所示:Java 停车场OO设计-枚举是否违反开放/关闭原则?,java,oop,object-oriented-analysis,Java,Oop,Object Oriented Analysis,我正在尝试使用面向对象的方法设计一个停车场系统。停车场可设置残疾人、小型、大型、摩托车等多种停车位 最初,我考虑创建一个枚举来对这些不同类型进行建模,如下所示: public enum ParkingSpotType { HANDICAPPED, COMPACT, LARGE, MOTORBIKE } public abstract class ParkingSpot { private ParkingSpotType type; } public class
public enum ParkingSpotType {
HANDICAPPED,
COMPACT,
LARGE,
MOTORBIKE
}
public abstract class ParkingSpot {
private ParkingSpotType type;
}
public class HandicappedSpot extends ParkingSpot {
}
public class CompactSpot extends ParkingSpot {
}
public class LargeSpot extends ParkingSpot {
}
public class MotorbikeSpot extends ParkingSpot {
}
然后在ParkingSpot
类中使用这些选项,如下所示:
public enum ParkingSpotType {
HANDICAPPED,
COMPACT,
LARGE,
MOTORBIKE
}
public abstract class ParkingSpot {
private ParkingSpotType type;
}
public class HandicappedSpot extends ParkingSpot {
}
public class CompactSpot extends ParkingSpot {
}
public class LargeSpot extends ParkingSpot {
}
public class MotorbikeSpot extends ParkingSpot {
}
类似地,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.getVehicleType().getParkingSpotType()
然而,有人告诉我,这将违反开放/封闭设计原则。任何新类型的添加都可能需要在各种现有位置更改代码,这将违反开放/封闭设计原则,即当需要引入新功能时,不应修改现有的和经过良好测试的类。有人建议我为不同的类型创建不同的子类,如下所示:
public enum ParkingSpotType {
HANDICAPPED,
COMPACT,
LARGE,
MOTORBIKE
}
public abstract class ParkingSpot {
private ParkingSpotType type;
}
public class HandicappedSpot extends ParkingSpot {
}
public class CompactSpot extends ParkingSpot {
}
public class LargeSpot extends ParkingSpot {
}
public class MotorbikeSpot extends ParkingSpot {
}
但使用这种方法,如果没有相同的枚举建模,我将如何将车辆映射到ParkingSpot。如果第一种方法确实是糟糕的wrt OO设计,请有人看看并评论一下。如果是,我将如何在第二种方法中解决上述问题?我不是专家,但我不理解对您的enum解决方案的批评。基于以下几点观察,我认为这很好: 打开/关闭原则允许扩展。这不仅包括创建接口和子类的新实现,还包括在现有类中添加属性和方法——“扩展”和“修改”之间的界限可能看起来很模糊,但据我所知,“打开/关闭”背后的原则是,如果某个客户机、使用者或模块正在使用您的代码库,他们不应该因为您的代码更改而进行重构(在理想情况下) 为此,我不认为向枚举添加新元素与添加扩展ParkingSpot的新类有什么不同。 可能是错的
我想我会问一个例子,如果我们添加了一个新的ParkingSpot枚举元素,当前代码会在哪里中断,但如果我们向ParkingSpot添加了一个新的子类,则不会中断当前代码,因为我目前没有看到任何子类。我不是专家,但我不理解对您的枚举解决方案的批评。基于以下几点观察,我认为这很好: 打开/关闭原则允许扩展。这不仅包括创建接口和子类的新实现,还包括在现有类中添加属性和方法——“扩展”和“修改”之间的界限可能看起来很模糊,但据我所知,“打开/关闭”背后的原则是,如果某个客户机、使用者或模块正在使用您的代码库,他们不应该因为您的代码更改而进行重构(在理想情况下) 为此,我不认为向枚举添加新元素与添加扩展ParkingSpot的新类有什么不同。 可能是错的 我想我会问一个例子,如果我们添加了一个新的ParkingSpot枚举元素,当前代码会在哪里中断,但如果我们向ParkingSpot添加了一个新的子类,则不会中断,因为我目前没有看到任何子类。因为问题是“枚举是否违反打开/关闭原则?”我的答案是,由于您无法编写枚举类型的子类,并且枚举类型的用户无法创建自己的实例来满足自己的需求,因此在大多数情况下,这将违反打开/关闭原则,但有两个警告:
- 如果枚举类型本质上是一个穷举列表(例如,一周中的几天),那么它就不需要“开放扩展”,因为整数不需要“开放扩展”
- 如果枚举类型的方法在传递满足某些接口(例如排序函数的
)的用户定义类时可能具有不同的行为,则它在该意义上是“开放扩展”的。有关“开放供扩展”不一定意味着允许子类的讨论,请参阅compariable
ParkingSpotType
enum为一种类型的停车位建模,这样每个enum值都表示停车位的类型;而您的ParkingSpot
类对一个停车位进行建模,使得该类的一个实例(或其子类的一个实例,例如MotorbikeSpot
)表示一个单独的停车位,同一子类的多个实例将表示同一类型的不同停车位。考虑:
- 您可以使用enum
来表示不同类型的停车位,也可以使用enumParkingSpotTypes
来表示特定停车场中的实际停车位(如果程序只需要为一个停车场工作,则有一个明确的列表)ParkingSpots
- 您可以使用一个类
来表示一个实际的停车位,其中包含不同类型停车位的子类,或者您可以使用一个类ParkingSpot
,其实例分别表示一种停车位类型parkingspotype