27

我遇到了不同的面试,有人问我为什么要使用封装?谁的要求实际上是封装?是给程序用户的吗?还是为了同事?还是为了保护代码免受黑客攻击?

4

5 回答 5

41

封装有助于将实现细节与暴露给类的客户端(使用此类的其他类/函数)的行为隔离开来,并让您更好地控制代码中的耦合。考虑这个例子,类似于 Robert Martin 的书Clean Code中的例子:

public class Car
{
//...
public float GetFuelPercentage() { /* ... */ };

//...

private float gasoline;
//...
}

请注意,使用为您提供汽车燃料量的功能的客户端并不关心汽车使用哪种燃料。这种抽象将关注点(燃料量)与不重要的(在这种情况下)细节分开:无论是天然气、石油还是其他任何东西。

第二件事是类的作者可以自由地对类的内部做任何他们想做的事情,例如将汽油换成油,以及其他事情,只要他们不改变它的行为。这要归功于这样一个事实,即他们可以确定没有人依赖这些细节,因为它们是私人的。代码中的依赖项越少,它就越灵活且易于维护。

utnapistim在低估的答案中正确指出了另一件事:低耦合还有助于测试代码并维护这些测试。类的接口越简单,测试就越容易。没有封装,所有东西都暴露出来,很难理解要测试什么以及如何测试。

重申评论中的一些讨论:

  • 不,封装不是OOP中最重要的事情。我什至敢说这不是很重要。封装鼓励了重要的事情——比如松散耦合。但这不是必需的——细心的开发人员可以在不封装变量等的情况下保持松散耦合。正如vlastachu所指出的,Python 是一种没有强制封装机制的语言的一个很好的例子,但它对于 OOP 仍然是可行的。

  • 不,将您的字段隐藏在访问器后面不是封装。如果您所做的唯一一件事就是在变量前面写“private”,然后盲目地为每个变量提供 get/set 对,那么实际上它们没有被封装。代码中遥远的地方的人仍然可以干预您的类的内部,并且仍然可以依赖它们(当然,它们依赖于方法而不是字段会更好一些)

  • 不,封装的主要目标不是避免错误。主要目标至少与上面列出的类似,认为封装可以保护您免于犯错是幼稚的。除了更改私有变量之外,还有很多其他方法可以犯错误。并且更改私有变量并不难找到和修复。再说一遍——为了这个论点,Python 是一个很好的例子,因为它可以在不强制执行的情况下进行封装。

于 2013-08-18T16:03:58.310 回答
22

封装通过确保他们只访问他们应该访问的东西来防止处理您的代码的人犯错误。

于 2013-08-18T15:58:09.650 回答
20

At least in most OO languages, encapsulation is roughly equivalent to the lock on the door of a bathroom.

It's not intended to keep anybody out if they really insist on entering.

It is intended as a courtesy to let people know that entering will lead mostly to:

  1. embarrassment, and
  2. a stinking mess.
于 2013-08-18T16:16:46.260 回答
14

封装允许您形式化您的接口,分离抽象级别(即“应用程序逻辑仅以这种方式访问​​ IO 代码”)。

这反过来又允许您在不更改接口(并影响客户端代码)的情况下更改模块的实现(模块内的数据和算法)。

这种相互独立修改模块的能力提高了您衡量绩效和预测项目截止日期的能力。

它还允许您单独测试模块并在其他项目中重用它们(因为封装还降低了相互依赖性并提高了代码的模块化)。

不强制封装往往会导致项目失败(问题随着项目的复杂性而增长)。

于 2013-08-18T16:03:18.313 回答
7

我设计了一个快速通道项目。封装减少了变化在系统中的传播。改变需要时间和金钱。

当代码没有被封装时,一个人必须搜索许多文件才能找到在哪里进行更改。不利的是,有“我找到所有地方了吗?”的问题。另一点“对整个系统进行所有这些分散更改有什么影响?”

我正在研究嵌入式医疗设备,质量是必不可少的。此外,所有更改都必须记录、审查、单元测试,最后执行系统测试。通过使用封装,我们可以减少更改的数量及其位置,减少必须重新测试的文件数量。

于 2013-08-18T17:57:52.583 回答