为什么封装是OOP语言的一个重要特性?

Sha*_*zad 22 architecture oop encapsulation software-design

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

Bar*_*zKP 35

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

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

//...

private float gasoline;
//...
}
Run Code Online (Sandbox Code Playgroud)

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

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

还有一两件事,在正确地指出了被低估的答案utnapistim:低耦合也有助于测试代码,并保持这些测试.类的界面越简单,就越容易测试它.没有封装,暴露的一切都很难理解测试的内容和方式.

重申评论中的一些讨论:

  • 不,封装不是OOP中最重要的事情.我甚至敢说它不是很重要.封装所鼓励的重要事项 - 如松耦合.但它并不重要 - 一个细心的开发人员可以保持松耦合而不封装变量等.正如vlastachu所指出的,Python是一个很好的例子,它没有机制来强制执行封装,但它仍然适用于OOP.

  • 不,隐藏在访问后面的字段不是封装.如果你唯一做的就是在变量前写"私有",然后盲目地为每个变量提供get/set对,那么实际上它们并没有被封装.有人在代码中一个遥远的地方仍然可以与你的类的内部染指,而且还可以依靠他们(当然,这是当然的一点更好,他们依靠的方法,而不是一个字段).

  • 不,封装的主要目标不是避免错误.主要目标至少与上面列出的目标类似,并且认为封装将防止您犯错误是天真的.除了改变私有变量之外,还有很多其他方法可以犯错误.改变私有变量并不难找到并修复.再次 - 对于这个参数,Python是一个很好的例子,因为它可以在不强制执行的情况下进行封装.

  • 这个答案谈论的是抽象,而不是封装。 (2认同)
  • @Euphoric 问题是它的用途是什么。显然这不是为了它本身,这就是为什么我要解释它的目的,而不是它是什么。正如您所正确指出的,抽象就是它的用途。 (2认同)

SLa*_*aks 18

封装可以防止处理代码的人犯错,确保他们只访问他们应该访问的内容.

  • @MShahzad:因为如果他们访问一个“私有”字段,他们会得到一个编译器错误。 (2认同)
  • 更好的措辞:"*访问修饰符*防止你的代码上的人错误地破坏封装".巴托斯的答案可以更好地回答你为什么要首先进行封装.正如M Shahzad暗示的那样,他们没有采取任何措施来阻止任何其他类型的错误. (2认同)

Jer*_*fin 13

至少在大多数OO语言中,封装大致相当于浴室门上的锁定.

如果他们真的坚持要进入,那么它并不打算让任何人离开.

出于礼貌,让人们知道进入将主要导致:

  1. 尴尬,和
  2. 一团糟.


utn*_*tim 12

封装允许您将接口形式化,分离抽象级别(即"应用程序逻辑仅以此方式访问IO代码").

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

这种相互独立地修改模块的能力可以提高您衡量绩效的能力,并在项目的最后期限内进行预测.

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

不执行封装往往会导致项目失败(问题随着项目的复杂性而增加).


Tho*_*ews 7

我构建了一个快速通道项目.封装减少了通过系统的变化传播.改变花费时间和金钱.

如果未封装代码,则必须搜索许多文件以查找进行更改的位置.相反,有一个问题是"我找到了所有的地方吗?" 另一点"整个系统对所有这些分散变化有什么影响?"

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