QR code

remove(42) vs. find(42).remove()

  • Translated by to

我们在books对象中有一本书的列表。我们如何从中删除一本书,假设我们知道它的ID?我们可以使用books.removeById(42)。另外,我们可以使用books.findById(42)来找到它,然后调用b.remove()。我们应该选择哪个选项,为什么?第二个选择是更好的。不仅因为它更面向对象,而且还有几个实际优势。

如果我们想要扩展删除算法怎么办?例如,假设我们希望在删除书籍时打印一条日志消息。

如果我们遵循开闭原则,我们应该避免修改现有的BookBooks类。相反,我们希望扩展或装饰它们。如果我们想避免实现继承,装饰器是理想的选择。

如果我们使用removeById(),我们必须装饰books对象。如果我们使用remove(),我们可以装饰通过findById()检索到的单个书籍。后一种方法可能更具内聚性,因为其装饰对象可能更和更专注

Handling Missing or Non-Deletable Books

如果找不到书籍或无法删除该书籍怎么办?removeById()方法并不很好地支持Null Object模式。它强迫我们抛出异常—或者更糟糕的是返回false,这违背了CQRS原则。

另一方面,返回一个对象,即使是一个null或假对象,提供了更多的灵活的错误处理。例如,我们可以安全地访问title(),知道书籍已成功找到—或者捕获并带有更多上下文重新引发异常:

Decoupling Retrieval and Deletion

如果对象的检索和删除在代码中相隔较远会怎样呢?

如果 books 知道如何找到,而 book 知道如何删除,我们可以很好地将责任分开。这也允许书籍是不可变的,并封装自己的 ID,减少内部数据的泄漏:

一旦ID被findById()包裹在书中,它就再也不必泄漏出来了。这减少了暴露给不需要的代码部分的裸数据量。

可见数据越少,设计就越好—至少从面向对象编程的角度来看。

因此,使用findById()后跟remove()更全面地拥抱面向对象的原则。它允许更清晰的扩展、更好的错误处理和更紧密的封装。

Translated by ChatGPT gpt-3.5-turbo/42 on 2025-06-22 at 14:22

sixnines availability badge  GitHub stars