Quelle est la différence entre "couche d'abstraction" et "niveau d'indirection"?

38

Je ne suis pas sûr que les deux termes puissent être utilisés de manière interchangeable. Peut-être existe-t-il une distinction théorique en informatique qui ne soit pas pertinente pour la programmation quotidienne? Ou puis-je utiliser les deux termes de manière interchangeable sans me tromper? Peut-être que cela dépend du contexte dans lequel j'utilise les deux termes?

Edit: La raison pour laquelle je trouve les deux termes potentiellement interchangeables est une entrée Wikipedia sur la couche d’abstraction . Vous y trouverez David Wheelers citant "Tous les problèmes informatiques peuvent être résolus par un autre niveau d'indirection".

Theo Lenndorff
la source
7
... sauf le problème de trop de niveaux d'indirection!
Mason Wheeler
@MasonWheeler: Vous pouvez ajouter un autre niveau d'indirection moins indirect…
Jon Purdy,
C ++ vous permet d’ajouter une couche d’abstraction sans couche d’indirection, afin qu’elles ne puissent pas avoir le même sens.
fredoverflow

Réponses:

30

L'abstraction traite de la simplification, l' indirection traite de la localisation.

  • Abstractionest un mécanisme qui "cache" les détails compliqués d'un objet en termes de termes plus simples et plus faciles à manipuler. En programmation, un bon exemple est la différence de détail entre le code machine et les divers outils permettant de créer des applications qui sont finalement basées sur le code machine. Pensez à créer une application Windows Form avec l'EDI de Visual Studio. L'EDI vous permet de penser à l'application en termes d'éléments faciles à manipuler de manière à ce que vous voyez. La position d'un widget d'écran est abstraite en un emplacement visuel dans un cadre que vous pouvez modifier en faisant glisser le widget. En interne, l'EDI manipule le widget en utilisant une autre couche d'abstraction telle qu'un langage de haut niveau (tel que C #). C # lui-même n'est pas manipulé à l'aide de code machine, il est manipulé à l'aide d'un "environnement d'exécution commun"

  • L'indirection consiste à rendre l'emplacement d'un élément transparent. Si vous connaissez l'URI d'une ressource Web, vous pouvez accéder à la ressource sans connaître son emplacement précis. Vous n’accédez pas directement à la ressource, mais par l’intermédiaire d’un canal qui transmet votre demande à une série de serveurs, d’applications et de routeurs. L'indirection peut être considérée comme un type spécial d'abstraction où la localisation est abstraite.

Jay Elston
la source
2
+1 meilleure réponse jusqu'à présent! Était sur le point d'écrire un, mais celui-ci est assez proche de ce que j'avais en tête.
Newtopian
27

Les abstractions sont implémentées en utilisant l'indirection.

Par exemple, mémoire virtuelle: l’abstraction est un espace adresse contigu à votre entière disposition. Cette abstraction est implémentée en utilisant l'indirection via une table de pages. Au lieu d'accéder directement aux adresses de mémoire physique, elles sont traduites d'une adresse virtuelle en une adresse physique.

Pour ajouter une couche d'abstraction, vous devez ajouter une couche d'indirection. Mais ajouter une indirection ne vous donne pas nécessairement une abstraction. Par exemple, avoir des getters et des setters sur chaque variable est une couche d'indirection, mais si tout ce qu'ils font est d'obtenir et de définir des valeurs simples, il n'y a pas d'abstraction.

Austin
la source
2
En fait, le dernier exemple n'est pas très bon. Les getters et les setters ordinaires ajoutent de l'abstraction. Le seul à savoir, ils sont clairs, est la classe qui les déclare. Si vous décidez de modifier l'implémentation, le code généré contre l'abstraction n'est pas affecté.
back2dos
pouvez-vous donner un meilleur exemple qui est indirection mais pas abastraction?
M. Coder,
1
certainement un mauvais exemple
Morg.
3
Qui a parlé des cours? Je n'ai également rien dit sur la modification de la visibilité d'une variable. Rien ne vous empêche d'y accéder directement; c'est une variable. Mais vous pouvez également le faire avec un niveau d'indirection via le getter et le setter. Comme la sémantique d'utilisation de getter et de setter est identique à l'accès direct à la variable, il n'y a pas d'abstraction.
Austin
2
Sauf que le getter et le setter n'accèdent pas nécessairement à la variable. Si vous utilisez un getter et un setter, vous ajoutez une abstraction car vous pouvez les changer pour utiliser une variable différente sans que l'utilisateur en soit conscient, donc une abstraction.
Dominique McDonnell
9

Premièrement, essayons les définitions appropriées pour les termes:

  1. Couche d'abstraction signifie:

     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. Le niveau d'indirection, par contre, signifie:

      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
    

Ces deux choses peuvent signifier la même chose, tant que vous utilisez:

  a) step = going from simple code to complex code. 
tp1
la source
7

Si j'ai bien compris, l'abstraction fait principalement référence à des fonctions et l'indirection, à des données. En d'autres termes, le niveau d'abstraction correspond à la profondeur de votre trace de pile et le niveau d'indirection correspond au nombre de pointeurs que vous devez déréférencer. Au moins c'est comme ça que j'utilise les termes.

Karl Bielefeldt
la source
avec des fonctions virtuelles modélisées comme des pointeurs vers des fonctions?
Caleth
7

Couche d'abstraction et niveau d'indirection sont des concepts distincts. L'abstraction est l'agrégation et la dénomination significative d'un certain nombre d'éléments tels que des éléments de données ou des instructions de programme, par exemple le concept d'appel de fichier ou de méthode, alors que l'indirection est le découplage d'entités pour faciliter le report de la réalisation de leur relation. Par exemple, l'utilisation de JNDI pour séparer l'identification d'une ressource dans un programme de la ressource réelle qui peut éventuellement être fournie par un conteneur d'application.

Fréquemment, les concepts vont de pair et que l’on applique à une construction particulière dépend de l’exercice ou de la discussion en cours. Par exemple, la nature abstraite d’une interface est importante lors de l’apprentissage ou de la documentation d’une API; sa propriété d'indirection est importante lors de l'ajout d'extensibilité ou de la création de tests pour une application.

Une couche d'abstraction est l'agrégation d'abstractions et leur confère une intégrité conceptuelle et une cohérence d'utilisation. CreateProcess est le nom de l'API win32 pour un groupe de code qui construit et exécute un processus. Le "nom" est significatif pour ce contexte car si nous appelions la fonction par quelque chose comme DoAllocMemThenMakeEnvThenFindEntryPoint ... ce ne serait vraiment pas très abstrait. Une couche telle que l'API Win32 constitue une barrière sur laquelle un programmeur peut être avisé de ne pas s'aventurer. Il supprime la complexité du point de vue de l'appelant au détriment de la consommation d'énergie (flexibilité, performances, etc.). Ce compromis est mis en évidence par les discussions fréquentes sur les abstractions présentant des fuites: nous aurons peut-être encore besoin de passer des appels SQL directs lorsque nous utilisons Hibernate ou de faire des appels Win32 avec .NET.

En ce qui concerne l'indirection, la plupart des programmes non triviaux fonctionnent avec une certaine forme d'indirection codée par l'utilisateur, comme l'indique la section INPUT-OUTPUT de COBOL avant l'arche. Lors de l'accès à une ressource telle qu'une base de données, il est possible que l'intégration d'une chaîne de connexion JDBC dans le code soit indirectionnelle de niveau 0, une connexion JNDI (qui délègue le choix de la ressource à un conteneur d'application) en tant que niveau 1 et une construction Spring mappant l'identificateur JNDI de l'application à l'une des nombreuses ressources de conteneur de niveau 2. Plusieurs niveaux permettent à un nombre de parties externes à la relation (dans ce cas, une relation entre le code en cours d'exécution et une base de données) de manipuler cette relation. Ceci s'applique également aux composants de programme internes tels que les interfaces et les événements.

Nous voyons que, quelles que soient leurs autres qualités, l’abstraction réduit la complexité alors que l’indirection l’augmente. L'abstraction réduit le pouvoir alors que l'indirection augmente. L'indirection peut être utilisée pour restaurer la puissance de l'abstraction en permettant au comportement par défaut d'être remplacé par des rappels personnalisés.

Mikemay
la source
1

Un pointeur sur un pointeur sur un pointeur sur un pointeur sur un pointeur sur un pointeur sur int a six niveaux d'indirection, mais aucune couche d'abstraction.

gnasher729
la source
0

Un bon exemple d'abstraction consiste à appeler une seule méthode pour stocker un élément dans une base de données. La méthode résume les détails de la connexion et de l'appel de la base de données. Où un exemple d'indirection utilise une structure pour accéder aux interruptions. Vous continuez d'accéder à l'interruption lorsque vous définissez des valeurs dans la structure. c'est simplement indirectement à travers la structure en donnant des noms de membre de structure à des points spécifiques en mémoire.

Donc, l'abstraction cache des détails d'implémentation où l'indirection fournit simplement une interface "indirecte" permettant d'accéder à quelque chose.

L'abstraction est quand vous n'avez pas besoin de comprendre ce qui est caché, où vous faites avec indirection.

Charles Lambert
la source
-1

L'ajout d'un niveau (ou couche) d'abstraction et d'un niveau d'indirection sont simplement les deux façons de dire la même chose. Lorsque vous résolvez un problème, vous essayez généralement une solution directe. Parfois, ce n'est pas possible, alors vous essayez une solution indirecte. Cela nécessite l'introduction d'une certaine abstraction pour simplifier le problème - car c'est un problème complexe qui ne peut pas être résolu directement. Après avoir résolu le problème par l’approche indirecte, il n’ya aucune raison de ne pas envisager de résoudre le problème à nouveau, mais plus généralement; Cela impliquera d'introduire un autre niveau d'abstraction plus élevé. Et cette nouvelle solution plus générale est encore plus indirecte que la solution indirecte originale, c’est-à-dire qu’un autre niveau d’indirection a été introduit.

ChrisC
la source
3
cela ne semble rien ajouter de substantiel aux points soulevés et expliqués dans les 7 réponses précédentes
gnat
Merci, Gnat. Je comprends ce que vous dites, et c'est dommage que cette question intéressante attire beaucoup de spam!
ChrisC