java - 我在这个例子中是否违反了 LSP 原则?
问题描述
我有实现两种门的代码。一扇门有锁,另一扇没有。
Door界面很简单:
public interface Door {
void open();
void close();
}
然后我有实现:LockedDoor和RegularDoor
public class LockedDoor implements Door {
private Lock lock;
private boolean isOpen;
@Override
public void open() {
if(!lock.isLocked()) {
this.isOpen = true;
}
}
@Override
public void close() {
this.isOpen = false;
}
}
public class RegularDoor implements Door {
private boolean isOpen;
@Override
public void open() {
isOpen = true;
}
@Override
public void close() {
isOpen = false;
}
}
如您所见,LockedDoor
只有当锁被解锁时, 的打开功能才会打开门。
您可以通过接收它LockedDoor
并调用它的解锁函数来解锁锁。
是否违反了里氏替换原则?
如果是的话,什么是一个好的选择?
解决方案
回答这个问题有点困难,因为您的界面Door
似乎不完整,因为不清楚什么open()
和close()
应该做什么。让我们通过添加一个方法来清除它isOpen()
,并定义一次open()
调用,随后的调用isOpen()
应该返回true
(为了简洁起见,我故意忽略如果您尝试打开并且已经打开门会发生什么的问题)。
在这种情况下,你肯定违反了 LSP 原则——如果你试图打开一扇上锁的门,你会失败,而门将保持关闭状态。
解决此问题的一种方法是向open()
andclose()
方法添加返回值,以便它们可以报告操作是否成功:
public interface Door {
/**
* Checks if the door is open.
* @return {@code true} if the door is open, {@code false} if not.
boolean isOpen();
/**
* Attempt to open the door.
* @return {@code true} if the door was successfully opened,
* {@code false} if not.
* In other words, if a call to {@code open} returns {@code true}, a
* subsequent call to {@link #isOpen} will return {@code true}.
*/
boolean open();
/**
* Attempt to close the door.
* @return {@code true} if the door was successfully closed,
* {@code false} if not.
* In other words, if a call to {@code close} returns {@code true}, a
* subsequent call to {@link #isOpen} will return {@code false}.
*/
void close();
}
public class RegularDoor implements Door {
private boolean isOpen;
@Override
public boolean isOpen() {
return isOpen;
}
@Override
public boolean open() {
return isOpen = true;
}
@Override
public boolean close() {
return isOpen = false;
}
}
public class LockedDoor implements Door {
private Lock lock;
private boolean isOpen;
@Override
public boolean isOpen() {
return isOpen;
}
@Override
public boolean open() {
if (!lock.isLocked()) {
return isOpen = true;
}
return false;
}
@Override
public boolean close() {
return isOpen = false;
}
// Not shown here - methods to lock and unlock the door
}
推荐阅读
- node.js - Axios 400 React 中的错误请求
- database - MongoDB - 具有父子关系的数据库设计
- ios - iOS 13.3.1 dyld:库未加载
- c++ - RegCreateKeyExA 函数返回 ERROR_INVALID_PARAMETER(错误代码 87)
- laravel - 如何在 Laravel 中安装 Chart.js?
- postman - 如何使用 Postman 发送 HTTP 200 响应
- c# - 如何重新实现 ObservableCollection.this[index]
- python - 为什么 pip 只从缓存中安装包?
- google-cloud-dlp - Google Cloud DLP API:默认安全通信
- r - R中的正则表达式负后视案例