“抽象层”和“间接级别”之间有什么区别?


38

我不确定这两个术语是否可以互换使用。也许计算机科学上有一些学术上的区别与日常编程无关?还是我可以在不误的情况下互换使用这两个术语?也许这取决于我同时使用这两个术语的环境?

编辑:关于为什么我发现两个术语可能可以互换的原因是有关抽象层Wikipedia条目。在那里,您可以找到David Wheelers引述的“计算机科学中的所有问题都可以通过另一种间接解决方案来解决。”


7
...除了过多的间接级别问题!
梅森惠勒

@MasonWheeler:您可以添加另一个更间接的间接级别…
Jon Purdy

C ++允许您添加一个抽象层而没有一个间接层,因此它们不能表示相同的意思。
fredoverflow 2011年

Answers:


30

抽象涉及简化,间接涉及位置。

  • 抽象化是一种以更简单,更易于操作的术语“隐藏”对象的复杂细节的机制。在编程中,一个很好的例子是机器代码和各种最终基于机器代码创建应用程序的工具之间的细节差异。考虑使用Visual Studio IDE创建Windows窗体应用程序。通过IDE,您可以按照“看得到即得到”的方式通过易于操作的项目来思考应用程序。屏幕小部件的位置被抽象到框架中的可视位置,您可以通过拖动小部件来更改它。在内部,IDE使用另一种抽象层(例如高级语言(例如C#))来操纵小部件。C#本身不使用机器代码进行操作,而是使用“公共运行时环境”进行操作

  • 间接是指使项目的位置透明。如果您知道Web资源的URI,则可以在不知道其确切位置的情况下访问该资源。您不会直接访问资源,而是会通过将请求传递到一系列服务器,应用程序和路由器的通道进行访问。间接可以被认为是一种抽象的特殊类型,其中位置被抽象了。


2
到目前为止,+ 1个最佳答案!正要写一个,但是这个和我的想法已经足够接近了。
Newtopian 2011年

27

抽象是使用间接实现的。

例如,虚拟内存:抽象是一个连续的地址空间,完全由您使用。通过页面表使用间接实现该抽象。它们不是直接访问物理内存地址,而是从虚拟地址转换为物理地址。

要添加一个抽象层,您必须添加一个间接层。但是添加间接并不一定会给您一个抽象。例如,在每个变量上都具有getter和setter只是一个间接层,但是如果它们所做的只是获取并设置简单值,则没有抽象。


2
实际上,最后一个例子不是很好。普通的getter和setter确实添加了抽象。唯一知道的是,类是声明它们的类。如果决定更改实现,则不影响针对抽象构建的任何代码。
back2dos

你能举一个更好的例子,间接的而不是抽象的吗?
Coder先生

1
绝对是一个错误的例子
莫格。

3
谁对课程说过什么?我也没有说过改变变量的可见性。没有什么可以阻止您直接访问它;这是一个变量。但是您也可以通过getter和setter在一定程度上进行间接操作。由于使用getter和setter的语义与直接访问变量的语义相同,因此没有抽象。
奥斯汀

2
除了getter和setter不一定“仅”访问变量。如果您使用的是getter和setter方法,那么您将添加一个抽象,因为您可以将它们更改为使用其他变量,而用户不会意识到,因此是一个抽象。
Dominique McDonnell '10

9

首先,让我们为这些术语尝试正确的定义:

  1. 抽象层意味着:

     a) there is large number of positions which use abstraction
          (layer = all the positions together)
     b) each position is hiding some complex stuff, but allows invoking it 
          using only simple code. 
         (abstraction == one-to-one mapping between simple code and complex code)
    
  2. 另一方面,间接级别意味着:

      a) you're counting levels
      b) indirection==there are several steps before you can reach or access the data
      c) level of indirection is just how many steps it takes to access the data
    

只要您使用以下两种方法,就意味着同一件事:

  a) step = going from simple code to complex code. 

7

我的理解是抽象主要指功能,而间接主要指数据。换句话说,抽象级别是堆栈跟踪的深度,而间接级别是必须取消引用的指针的数量。至少这就是我使用这些术语的方式。


虚拟函数被建模为函数的指针?
卡雷斯(Caleth)'17

7

抽象层和间接级别是不同的概念。抽象是许多元素的聚合和有意义的命名,例如数据或程序指令,例如文件或方法调用的概念,而间接是实体的解耦,以促进推迟实现它们之间的关系,例如,使用JNDI将程序中资源的标识与实际资源分开,后者可能最终由应用程序容器提供。

这些概念经常是并行的,哪种概念适用于特定的构造取决于进行中的练习或讨论。例如,在学习或记录API时,接口的抽象性质很重要;在为应用程序添加可扩展性或为其创建测试时,其间接属性非常重要。

抽象层是抽象的集合,并赋予它们概念上的完整性和用法的一致性。CreateProcess是用于构建和执行过程的一堆代码的win32 API名称。“名称”在这种情况下很重要,因为如果我们调用类似DoAllocMemThenMakeEnvThenFindEntryPoint之类的函数,那么它实际上并不是很抽象。诸如Win32 API的层提供了一个屏障,建议程序员不要冒险穿越该屏障。它以降低功耗(灵活性,性能等)为代价,从呼叫者的角度消除了复杂性。通过频繁讨论泄漏抽象来突出这种权衡:使用Hibernate时,我们可能仍需要直接SQL调用,而使用.NET时,则需要进行Win32调用。

关于间接,大多数非平凡的程序都以某种形式的用户编码的间接操作,从方舟之前见证了COBOL的INPUT-OUTPUT部分。当访问诸如数据库之类的资源时,我们可能会看到JDBC连接字符串在代码中的嵌入为级别0间接访问,JNDI连接(将资源的选择委托给应用程序容器)嵌入为级别1,并且一些Spring构造可以映射应用程序JNDI标识符作为级别2的许多容器资源之一。多个级别允许该关系(在本例中为执行代码和数据库之间的关系)外部的多个参与者来操纵该关系。这同样适用于内部程序组件,例如接口和事件。

我们看到,无论其他质量如何,抽象都会降低复杂性,而间接提高它。抽象降低了功耗,而间接提高了。通过允许默认行为被自定义回调覆盖,可以使用间接调用来恢复抽象的功能。


1

指向指针的指针指向int指针的指针具有六个间接级别,但是没有任何抽象层。


0

一个很好的抽象示例是调用单个方法将项目存储在数据库中。该方法抽象了连接和调用数据库的详细信息。间接寻址的示例使用结构访问中断。在结构中设置值时,您仍在访问中断。它只是通过将结构成员名称赋予内存中的特定点而间接地通过该结构。

因此,抽象隐藏了实现的细节,其中间接提供了一个简单的“间接”接口来访问某些内容。

抽象是指您不需要了解隐藏的内容以及使用间接方法进行的操作。


-1

添加抽象级别(或层)和间接级别是表达同一件事的两种简单方法。解决问题时,通常会尝试直接解决方案。有时这是不可能的,因此您尝试使用间接解决方案。这需要引入一些抽象来简化问题-因为这是一个复杂的问题,无法直接解决。通过间接方法解决了问题,没有理由不考虑再次解决问题,而是更普遍地考虑;这将涉及引入另一个更高级别的抽象。而且这种新的,更通用的解决方案甚至比原始的间接解决方案更具间接性-即,因此引入了另一种间接级别。


3
在先前的7个答案中所提出和解释的观点看来,这似乎并没有增加任何实质性的内容
gnat

谢谢,纳特 我同意你的观点,可惜这个有趣的问题吸引了很多垃圾邮件!
克里斯C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.