[英]ID and EAN inheritance may violate Liskov Substitution Principle
I have a design question for my application. 我对我的应用程序有一个设计问题。
I have a product and a category. 我有一个产品和一个类别。 Both must have an ID. 两者都必须有一个ID。
Category can have any positive integer as an ID. 类别可以具有任何正整数作为ID。 (-> Id-class) (-> ID级)
Product must have an positive integer between 8 & 13 ciphers as an ID. 产品的ID必须为8到13个密码之间的正整数。 (-> Ean-class) (->精益班)
Since that's the only thing these classes do (create an id) and a getter/setter with the correct check. 由于这是这些类唯一的操作(创建ID)和具有正确检查的getter / setter方法。
To reduce code (DRY) I let Ean inherit from Id. 为了减少代码(DRY),我让Ean从ID继承。 But won't that violate Liskov (LSP)? 但是那不会违反Liskov(LSP)吗?
My question: 我的问题:
Thanks in advance! 提前致谢!
Identifier.java 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 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);
}
Is my LSP-reasoning correct? 我的LSP推理正确吗?
Answer: no 答:不可以
It looks like any place an Id is accepted, an Ean instance would be valid, right? 好像在任何地方都可以接受ID,一个Ean实例将是有效的,对吧? That's what LSP is all about. 这就是LSP的全部意义。 That's because Ean is a subset of valid Id's. 这是因为Ean是有效ID的子集。 Any Ean is a valid Id but the opposite isn't always true. 任何Ean都是有效ID,但并非总是如此。
Should I solve it with creating an interface? 我应该通过创建界面来解决它吗? (seems like duplicate code) Or is there another solution? (好像重复的代码)还是还有其他解决方案?
You could have an interface and two specific implementations (Id and Ean). 您可能有一个接口和两个特定的实现(Id和Ean)。 I would probably do that, because for me there's not reason to make Ean subclass Id. 我可能会这样做,因为对我而言,没有理由使Ean成为子类ID。 Both could implement a single interface aimed to serve as a identifier unit. 两者都可以实现旨在用作标识符单元的单个接口。
EDIT: The problem in your inheritance model is that an Ean instance could be inconsistent if you call setId() method inherited from parent class. 编辑:继承模型中的问题是,如果调用从父类继承的setId()方法,则Ean实例可能不一致。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.