【发布时间】:2010-03-09 17:16:35
【问题描述】:
我有一个关于实现这一点的最佳方法的问题。我将描述我当前的实现以及我是如何将自己画到一个角落的:
我有一个名为 Package 的抽象类:
public abstract class Package {
protected String description;
protected String packagingCode;
protected Dimension dimensions;
protected Weight weight;
protected Package() {
this.description = null;
this.packagingCode = null;
this.dimensions = null;
this.weight = null;
}
protected Package(String description, String packagingCode, Dimension dimensions, Weight weight) throws ShippingException {
this.description = description;
this.packagingCode = packagingCode;
this.dimensions = dimensions;
this.weight = weight;
String exceptionMessage = "";
if(!meetsWeightRequirements()) {
exceptionMessage = "This package's weight exceeds limits. ";
}
if(!meetsDimensionalRequirements()) {
exceptionMessage += "This package's dimensions exceed limits.";
}
if(!StringUtils.isEmpty(exceptionMessage)) {
throw new ShippingException(exceptionMessage);
}
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPackagingCode() {
return packagingCode;
}
public void setPackagingCode(String packagingCode) {
this.packagingCode = packagingCode;
}
public Dimension getPackageDimensions() {
return dimensions;
}
public void setPackageDimensions(Dimension dimensions) throws ShippingException {
this.dimensions = dimensions;
if(!meetsDimensionalRequirements()) {
this.dimensions = null;
throw new ShippingException("This package's dimensions exceed limits.");
}
}
public Weight getPackageWeight() {
return weight;
}
public void setPackageWeight(Weight weight) throws ShippingException {
this.weight = weight;
if(!meetsWeightRequirements()) {
this.weight = null;
throw new ShippingException("This package's weight exceeds limits.");
}
}
public abstract boolean meetsWeightRequirements();
public abstract boolean meetsDimensionalRequirements();
}
然后我有像这样扩展这个抽象类的类:
public class WeightBasedPackage extends Package {
public boolean meetsWeightRequirements() {
Weight weight = this.getPackageWeight();
boolean meetsRequirements = false;
if(weight != null) {
meetsRequirements = (weight.getWeight() > 0);
}
return meetsRequirements;
}
public boolean meetsDimensionalRequirements() {
return true;
}
}
我有另一个对象 (ShipRequest) 维护一个包列表 (List<Package>)。我还有一个服务(例如WeightBasedPackageShipService)使用这个对象并且可以访问这个包列表。此实现运行良好,因为服务并不真正关心它是什么类型的包。包之间的唯一区别是它们实现抽象方法的方式。
这就是问题所在。我创建了一个新类:
public class OrderQuantityPackage extends Package {
int quantity;
public OrderQuantityPackage() {
super();
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getQuantity() {
return this.quantity;
}
public boolean meetsWeightRequirements() {
return true;
}
public boolean meetsDimensionalRequirements() {
return true;
}
}
其中有一个quantity 字段。我需要访问服务中的这个字段 (OrderQuantityPackageShipService)。但是,由于它是 Package 类型,我必须强制转换它(看起来有点笨拙)。
我的问题是,我如何以更好的方式实现这一点(所以我不必强制转换)并确保类型安全(所以如果您使用 OrderQuantityPackageShipService,则包必须是 @ 类型987654331@)。我考虑过使用泛型,但对于我正在尝试做的事情似乎有点笨拙(ShipRequest 有许多其他属性,根据包的类型对其进行泛化似乎很奇怪)。
谢谢。
【问题讨论】:
-
我没有正确理解您的模型还是应该 OrderQuantityPackage 扩展 Package?
-
我的错,这是一个错字!
-
我不明白为什么你不能将你的 Package 转换为 OrderQuantityPackage,如果它将 Package 扩展为你的 OrderQuantityPackageShipService,因为它应该期望一个与其名称 OrderQuantityPackageShipService 相同的数量。我在这里错过了什么吗?
-
我已经更新了这个问题 - 我想可以投射,但我想知道是否有更好的方法来解决这个问题,这样它就不需要投射了。
-
就我而言,最好在有用的时候上最普通的课程。但是,在您的情况下,您似乎需要一个特定的类来完成这项工作,具体取决于您的运输服务。然后就是说,我会选择转换我的基类并确保它是 OrderQuantityPackage 类,并且可能在不是时抛出。否则,我会要求 OrderQuantityPackage 类的实例作为我的服务的输入参数。
标签: java design-patterns oop inheritance polymorphism