Java ID和EAN继承可能违反Liskov替换原则
我对我的申请有一个设计问题 我有一个产品和一个类别。两者都必须有一个ID 类别可以有任何正整数作为ID。->ID类 产品的ID必须为8到13个密码之间的正整数。->Ean类 因为这是这些类所做的唯一一件事,它们使用正确的检查来创建id和getter/setter 为了减少代码干涸,我让Ean从Id继承。但这不会违反Liskov LSP吗 我的问题: 我的LSP推理正确吗? 如果是: 我应该通过创建一个接口来解决这个问题吗?看起来像是重复的代码,或者有其他解决方案吗? 提前谢谢 Identifier.javaJava ID和EAN继承可能违反Liskov替换原则,java,oop,inheritance,design-patterns,liskov-substitution-principle,Java,Oop,Inheritance,Design Patterns,Liskov Substitution Principle,我对我的申请有一个设计问题 我有一个产品和一个类别。两者都必须有一个ID 类别可以有任何正整数作为ID。->ID类 产品的ID必须为8到13个密码之间的正整数。->Ean类 因为这是这些类所做的唯一一件事,它们使用正确的检查来创建id和getter/setter 为了减少代码干涸,我让Ean从Id继承。但这不会违反Liskov LSP吗 我的问题: 我的LSP推理正确吗? 如果是: 我应该通过创建一个接口来解决这个问题吗?看起来像是重复的代码,或者有其他解决方案吗? 提前谢谢 Identifie
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;
}
}
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);
}
我的LSP推理正确吗
回答:没有
看起来任何接受Id的地方,Ean实例都是有效的,对吗?这就是LSP的意义所在。这是因为Ean是有效Id的子集。任何Ean都是有效的Id,但相反的情况并不总是正确的
我应该通过创建一个接口来解决这个问题吗?看起来像是复制品
代码还是有其他解决方案
您可以有一个接口和两个特定的实现Id和Ean。我可能会这样做,因为对我来说,没有理由创建Ean子类Id。两者都可以实现一个接口,作为标识符单元
编辑:
继承模型中的问题是,如果调用从父类继承的setId方法,Ean实例可能不一致 setEan和getEan不应该存在。您应该替代setId。否则,任何人都可以在Ean上调用setId12L,从而在其中存储无效值。您也不应该从构造函数调用可重写的方法。标识符应该是不可变的IMHO。好了,现在setEan和getEan是get/setId。所以您应该创建一个单独的方法来检查EAN?否则,您将拥有两倍的签入构造函数和setter?这不是LSP问题的答案,但EAN实际上不应该被建模为数字。它是一个具有长度和校验和限制的数字字符串。