封装与数据隐藏(它们不一样)

Encapsulation vs data hiding (they are not the same)

我对封装和数据隐藏的整个术语有点困惑。我正在读重构大师写的“深入设计模式”一书,当他解释封装是什么时,我觉得有些不对劲。

我搜索了一下,找到了一个非常好的解释: .

他将封装误认为是数据隐藏。阅读上面 link 的答案后,我将其总结为这些定义:

encapsulation - 当我们从使用这些数据的一段代码、数据和方法中分离出来时,我们将它们打包在一起。 data hiding - 是一个我们可以做的一切的地方,我们做的是私有的,我们正在实现 getter 和 setter 作为我们可以访问这些数据的唯一地方。

但是随着我阅读的越多,我变得更加困惑。他做了一个话题: Encapsulate what varies。它有两个子类别 - 封装在方法级别和 class 级别。它说例如重制这个:

进入这个:

我认为这与上面 link 问题中的陈述相似。

Whatever changes encapsulate it. Protecting anything which is prone to change.

,对此的回答是:

(...) And 2, as noted by CommuSoft, isn't really a definition, it's a rule of thumb. And I will add that it's a rule of thumb about when to use data hiding, not encapsulation

所以现在,我有书中的这一部分,根据我给出的这个例子,我认为它更有可能是一个封装案例。但是,如果我的想法是正确的,并且它类似于 linked 主题中的引述,那么根据该答案,这个示例代码是关于何时使用数据隐藏的经验法则?所以总结一下......如果我正确理解封装和数据隐藏,我真的很困惑。根据我提供的那些例子,我认为这个例子是封装。这是正确的吗?如果是,那么它与引号中提到的主题有何不同?

我期待您的回答,如果整个解释不清楚,请给我反馈,我会尽力做得更好。

“封装”的通常定义是将数据——特别是状态——与对其进行操作的方法绑定在一起,而“数据隐藏”是限制对数据的访问数据,以便只能通过对其进行操作的那些方法来访问它。

使用这些定义,封装是数据隐藏的先决条件,因为这是您识别方法的方式特权访问数据直接。其他方式是可以想象的,但这就是用 OOP 语言完成的方式。

您所指的作者似乎在更广泛的意义上使用“封装”一词,将 逻辑 单元和数据绑定在一起,并提供接口保护消费者免受底层细节更改影响的逻辑或数据。

我认为这个词的用法没问题,因为:

  • 它表达了与数据绑定方法相同的目的
  • 没有其他词可以很好地表达这个概念;和
  • 在某种接口(不一定是 OOP“接口”)后面将事物绑定到一个单元的操作是您实现“关注点分离”和实施单一职责原则的方式。执行此操作是软件设计的全部内容,因此需要一个词。

在你给出的例子中,税率计算的细节被提取(封装)到它们自己的单元中,具有一个简单的接口(getTaxRate)。这是逻辑细节的封装,而不是数据,但它仍然有效。正如作者所说,这样做的原因是因为这些细节很容易发生变化,因此您不想在代码周围散布或复制它们——将它们聚集到一个地方并制作一个允许您更改的界面将来它们不会弄乱使用它们的所有代码。