Enllaç doble (informàtica)

En enginyeria de programari, l'enllaç doble és una forma especial d'enllaç múltiple i un mecanisme que envia una crida de funció a diferents funcions concretes en funció dels tipus d'execució de dos objectes implicats en la crida. En la majoria de sistemes orientats a objectes, la funció concreta que es crida des d'una crida de funció en el codi depèn del tipus dinàmic d'un únic objecte i, per tant, es coneixen com a crides d'enllaç únic, o simplement crides de funció virtuals.

Dan Ingalls va descriure per primera vegada com s'utilitzava el doble despatx a Smalltalk, anomenant-lo polimorfisme múltiple.[1]

Visió general

El problema general abordat és com enviar un missatge a diferents mètodes depenent no només del receptor sinó també dels arguments.

Amb aquesta finalitat, sistemes com CLOS implementen l'enllaç múltiple. L'enllaç doble és una altra solució que redueix gradualment el polimorfisme en sistemes que no admeten l'enllaç múltiple.

Casos d'ús

'enllaç doble és útil en situacions en què l'elecció del càlcul depèn dels tipus d'execució dels seus arguments. Per exemple, un programador podria utilitzar l'enllaç doble en les situacions següents: [2]

  • Ordenació d'un conjunt mixt d'objectes: els algorismes requereixen que una llista d'objectes estigui ordenada en algun ordre canònic. Decidir si un element arriba abans que un altre requereix coneixement dels dos tipus i possiblement d'algun subconjunt dels camps.
  • Els algorismes de col·lisió adaptatius solen requerir que les col·lisions entre diferents objectes es gestionen de diferents maneres. Un exemple típic és en un entorn de joc on la col·lisió entre una nau espacial i un asteroide es calcula de manera diferent a la col·lisió entre una nau espacial i una estació espacial.
  • Algorismes de pintura que requereixen que els punts d'intersecció dels sprites superposats es representin d'una manera diferent.
  • Els sistemes de gestió de personal poden enviar diferents tipus de treballs a diferents personals. Un algorisme schedule al qual se li dóna un objecte persona escrit com a comptable i un objecte de feina escrit com a enginyeria rebutja la programació d'aquesta persona per a aquesta feina.
  • Sistemes de gestió d'esdeveniments que utilitzen tant el tipus d'esdeveniment com el tipus d'objecte receptor per tal d'anomenar la rutina de gestió d'esdeveniments correcta.
  • Sistemes de panys i claus on hi ha molts tipus de panys i molts tipus de claus i cada tipus de clau obre múltiples tipus de panys. No només cal conèixer els tipus d'objectes implicats, sinó que el subconjunt de "informació sobre una clau concreta que és rellevant per veure si una clau en particular obre un pany determinat" és diferent entre els diferents tipus de bloqueig.

Doble enllaç en C++

A primera vista, l'enllaç doble sembla ser un resultat natural de la sobrecàrrega de funcions. La sobrecàrrega de funcions permet que la funció cridada depengui del tipus d'argument. La sobrecàrrega de funcions, però, es fa en el moment de la compilació utilitzant " name mangling " on el nom intern de la funció codifica el tipus de l'argument. Per exemple, una funció foo(int) es pot cridar internament__foo_iEs pot cridar i la funció foo(double)__foo_d. Per tant, no hi ha col·lisió de noms ni cerca de taules virtuals. Per contra, l'enllaç dinàmic es basa en el tipus d'objecte que fa la crida, és a dir, utilitza funcions virtuals (sobreescriure) en lloc de sobrecàrrega de funcions i resulta en una cerca de vtable. Considereu l'exemple següent, escrit en C++, de col·lisions en un joc: [3]

class SpaceShip {};
class ApolloSpacecraft : public SpaceShip {};

class Asteroid {
public:
  virtual void CollideWith(SpaceShip&) {
    std::cout << "Asteroid hit a SpaceShip\n";
  }
  virtual void CollideWith(ApolloSpacecraft&) {
    std::cout << "Asteroid hit an ApolloSpacecraft\n";
  }
};

class ExplodingAsteroid : public Asteroid {
public:
  void CollideWith(SpaceShip&) override {
    std::cout << "ExplodingAsteroid hit a SpaceShip\n";
  }
  void CollideWith(ApolloSpacecraft&) override {
    std::cout << "ExplodingAsteroid hit an ApolloSpacecraft\n";
  }
};

Doble enllaç en C#

En C#, quan es crida a un mètode d'instància que accepta un argument, es pot aconseguir l'enllaç múltiple sense utilitzar el patró de visitant. Això es fa utilitzant el polimorfisme tradicional alhora que es converteix l'argument en dinàmic.[4] L'enquadernador en temps d'execució triarà el mètode de sobrecàrrega adequat en temps d'execució. Aquesta decisió tindrà en compte el tipus de temps d'execució de la instància d'objecte (polimorfisme), així com el tipus de temps d'execució de l'argument.

Referències

  1. A Simple Technique for Handling Multiple Polymorphism. In Proceedings of OOPSLA '86, Object–Oriented Programming Systems, Languages and Applications, pages 347–349, November 1986. Printed as SIGPLAN Notices, 21(11). ISBN 0-89791-204-7
  2. «Visitor and Double Dispatch» (en anglès). [Consulta: 24 desembre 2023].
  3. Ardalis. «Double Dispatch in C# and DDD» (en anglès). [Consulta: 24 desembre 2023].
  4. «Using Type dynamic (C# Programming Guide)». Microsoft Developer Network. Microsoft, 30-09-2009. [Consulta: 25 maig 2016].