У меня вопрос о том, как лучше всего это реализовать. Я собираюсь описать мою текущую реализацию и то, как я, кажется, загнал себя в угол:
У меня есть абстрактный класс 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
пакет должен был иметь тип OrderQuantityPackage
). Я думал об использовании Generics, но мне кажется, что то, что я пытаюсь сделать, немного усложняет (ShipRequest
имеет кучу других атрибутов, и было странно обобщать его на основе типа пакета).
Спасибо.