我的申请有一个设计问题。
我有一个产品和一个类别。两者都必须有ID。
类别可以包含任何正整数作为ID。 ( - > Id-class)
产品必须具有介于8和8之间的正整数。 13个密码作为ID。 ( - > Ean-class)
因为这是这些类唯一做的事情(创建一个id)和一个带有正确检查的getter / setter。
为了减少代码(DRY),我让Ean从Id继承。但是不会违反Liskov(LSP)?
我的问题:
提前致谢!
Identifier.java
public class Identifier {
private Long id = 1000000000000L;
public Identifier(){
}
public Identifier(Long id){
setId(id);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Ean.java
public class Ean extends Identifier {
private final static int MIN_AMOUNT_OF_CIPHERS = 8;
private final static int MAX_AMOUNT_OF_CIPHERS = 13;
private final static String ERROR_EAN_LENGTH = "err_ean_length";
public Ean() {
}
public Ean(Long ean) throws DomainException {
setEan(ean);
}
public Long getEan() {
return getId();
}
public void setEan(Long ean) throws DomainException {
if (String.valueOf(ean).length() < MIN_AMOUNT_OF_CIPHERS
|| String.valueOf(ean).length() > MAX_AMOUNT_OF_CIPHERS) {
throw new DomainException(ERROR_EAN_LENGTH);
}
setId(ean);
}
答案 0 :(得分:0)
我的LSP推理是否正确?
答案:否
看起来任何地方都接受了Id,Ean实例会有效,对吗?这就是LSP的全部意义所在。这是因为Ean是有效身份证的子集。任何Ean都是有效的Id,但相反的情况并非总是如此。
我应该通过创建界面来解决它吗? (好像是重复的 代码)还是有其他解决方案吗?
您可以拥有一个界面和两个特定的实现(Id和Ean)。我可能会这样做,因为对我来说没有理由让Ean子类Id。两者都可以实现一个旨在充当标识符单元的单一界面。
修改强> 继承模型中的问题是,如果调用从父类继承的setId()方法,则Ean实例可能不一致。