Vad är en “Impedansmatchning” i programmering?

0
198
Shutterstock/oatawa

En programmeringsimpedansmatchning uppstår när data behöver omvandlas till ett annat arkitektoniskt paradigm. Det mest framträdande exemplet involverar objektorienterade kodbaser och relationsdatabaser.

En impedansmatchning uppstår när data hämtas från eller infogas i en databas. Egenskaperna för objekt eller klasser i kodbasen måste mappas till deras motsvarande databasfält.

Kartläggning och förhållanden

Dina klasser kartläggs inte nödvändigtvis direkt till enskilda databastabeller. Konstruktionen av ett objekt kan kräva att data från flera tabeller ska användas tillsammans.

Du måste också hantera förhållanden mellan dina data. Relationsdatabaser gör det enkelt genom att låta dig referera till andra poster. Du kan använda en JOIN för att komma åt alla data som är inkapslade av förhållandet.

SKAPA TABELL produktTyper & # 40; ProduktTypUuid VARCHAR & # 40; 32 & # 41; PRIMÄR NYCKEL, ProduktTypnamn VARCHAR & # 40; 255 & # 41; INTE NULL UNIK & # 41 ;; & nbsp; SKAPA TABELLprodukter & # 40; ProductUuid VARCHAR & # 40; 32 & # 41; PRIMÄR NYCKEL, produktnamn VARCHAR & # 40; 255 & # 41; INTE NULL UNIK, Produkttyp VARCHAR & # 40; 32 & # 41; INTE NULL, UTLÄNDSK NYCKEL & # 40; Produkttyp & # 41; REFERENSER productTypes & # 40; ProductTypeUuid & # 41; PÅ RADERA CASCADE & # 41 ;;

Med vanlig SQL kan du få de kombinerade egenskaperna för en produkt och dess produkttyp med den här enkla frågan:

SELECT * FROM products INNER JOIN productTypes ON ProductTypeUuid = ProductType; Annonsering

Sedan nås produktens egenskaper och dess produkttyp från samma plana struktur:

echo $ post & # 91; & quot; Produktnamn & quot; & # 93 ;; echo $ record & # 91; & quot; ProductTypeName & quot; & # 93 ;;

Denna platta array blir snabbt begränsande i komplexa applikationer. Utvecklare modellerar naturligtvis produkt- och produkttypenheterna som separata klasser. Produktklassen kan sedan innehålla en instans av en ProductType. Så här ser det ut:

slutklass ProductType & # 123; & nbsp; offentlig funktion __construct & # 40; offentlig sträng $ Uuid, offentlig sträng $ Namn & # 41; & # 123; & # 125; & nbsp; & # 125; & nbsp; slutklass Produkt & # 123; & nbsp; offentlig funktion __construct & # 40; public string $ Uuid, public string $ Name, public ProductType $ ProductType & # 41; & # 123; & # 125; & nbsp; & # 125;

Det finns nu en signifikant impedansöverensstämmelse i koden. Någon form av specialmappning krävs innan poster från databasfrågan kan representeras som produktinstanser.

Ytterligare komplikationer uppstår när du vill komma åt alla produkter av en viss typ. Så här kan du göra det i kod:

slutklass ProductType & # 123; & nbsp; offentlig funktion __construct & # 40; public string $ Uuid, public string $ Name, ProductCollection $ Products & # 41; & # 123; & # 125; & nbsp; & # 125;

Nu innehåller ProductType en ProductCollection, som i slutändan skulle innehålla en uppsättning produktinstanser. Detta skapar en dubbelriktad relationell referens & # 8211; ProductType innehåller alla sina produkter och varje produkt innehåller sin produkttyp.

Denna form av modellering finns inte i det relationella paradigmet. Varje anslutningsform representeras med en enda relationslänkpost. Användningen av dubbelriktade referenser förenklar utvecklarens tillgång till objektegenskaper. Det kräver dock mer komplex mappning när den överförs till och från databasen. Detta beror på att SQL inte förstår modellens semantik.

Hänsyn till hierarki

Annons

Modellen som förklaras ovan skapar en hierarki i kodbasen: Produkten ligger under ProductType. Detta låter logiskt och matchar våra förväntningar på den verkliga världen.

Relationsdatabaser respekterar inte hierarkier. Eftersom alla relationer är likvärdiga har relationsdatabaser en inneboende & # 8220; platt & # 8221; strukturera. Vi såg detta tidigare när vi hämtade data med en JOIN.

Bristen på hierarki i SQL betyder att alla tabeller har en motsvarande prioritet till varandra. En effekt av detta är att du enkelt kan komma åt egenskaperna för poster som är kapslade djupt i din logiska objekthierarki. Dessutom finns det en lägre risk för cykliska beroenden.

Exemplet ovan visar att Product och ProductType kan sluta hänvisa till varandra i kod; relationsdatabasernas platta karaktär skulle förhindra att detta specifika exempel inträffar. Cykler kan fortfarande dyka upp i vanlig SQL men det är mindre troligt att du stöter på dem än när du modellerar med objektorienterad kod.

Objektorienterad programmering förlitar sig på sammansättningen av enkla objekt till mer komplexa. Relationsmodeller har ingen sådan uppfattning om komposition eller det & # 8220; enkla & # 8221; och & # 8220; komplexa & # 8221; & # 8211; vilken post som helst kan referera till andra.

Arv

En annan OOP-exklusiv funktion är arv. Det är vanligt att en klass utökar en annan och lägger till ytterligare beteenden. Relationsdatabaser kan inte replikera detta. Det är omöjligt för ett bord att förlänga & # 8221; en annan tabell.

Annons

En kodbas som använder arv kommer att stöta på svårigheter när barnobjekt kvarstår eller hydratiseras via en relationsdatabas. Inom databasen behöver du vanligtvis två tabeller. En lagrar basobjektets egenskaper (som du utvidgar), medan en annan hanterar barnets egenskaper.

Mappningskoden upprepar sedan alla objektets egenskaper. Egenskaper som härrör från den utökade klassen kommer att införas i den första koden. De som definieras direkt på barnet hamnar i den andra tabellen.

Ett liknande system krävs när man mappar tillbaka till kodbasen från databasen. En SQL JOIN kan användas för att få alla poster som motsvarar basklassen (utökad), med underegenskaperna inkluderade. De poster som innehöll underegenskaperna skulle sedan mappas till barnklassinstanser.

SKAPA TABELL förälder & # 40; Id INTEGER PRIMÄR NYCKEL, EN INTEGER & # 41 ;; SKAPA TABELL barn & # 40; Id INTEGER PRIMÄR NYCKEL, B INTEGER, ParentId INTEGER & # 41 ;; klass Förälder & # 123; offentlig funktion __construct & # 40; int $ A & # 41; & # 123; & # 125; & # 125; & nbsp; slutklass Barn utvidgar förälder & # 123; offentlig funktion __construct & # 40; int $ A, int $ B & # 41; & # 123; & # 125; & # 125; & nbsp; //Skaffa poster //VÄLJ * FRÅN förälder INNRE GÅ MED barn PÅ barn.ParentId = förälder.Id; $ objs = & # 91; & # 93 ;; för varje & # 40; $ -post som $ -rekord & # 41; & # 123; om & # 40; är inställd & # 40; $ post & # 91; & quot; B & quot; & # 93; & # 41; & # 41; & # 123; $ objs & # 91; & # 93; = nytt barn & # 40; $ rekord & # 91; & quot; A & quot; & # 93 ;, $ rekord & # 91; & quot; B & quot; & # 93; & # 41 ;; & # 125; annars motsätter $ sig & # 91; & # 93; = ny förälder & # 40; $ post & # 91; & quot; A & quot; & # 93; & # 41 ;; & # 125;

Införandet av arv kräver användning av mer involverad kartläggningslogik. Möjligheten hos relationsdatabaser att modellera arvsmöjligheterna för objektorienterade språk introducerar denna impedansmatchning.

Synlighet och inkapsling

En grundläggande princip för objektorienterad programmering är synlighet och inkapsling. Fastigheter deklareras som offentliga eller privata. Ett objekts interna representation kan döljas bakom ett gränssnitt som förformaterar data för konsumenten.

Relationsdatabaser saknar dessa kontroller. Det finns inget sätt att förklara ett fält som privat, och det finns inte heller ett uppenbart behov av att göra det. Varje bit data som lagras i en databas har sitt eget syfte; det borde inte finnas någon överflöd.

Annons

Detta är inte nödvändigtvis sant när det transponeras till ett objektorienterat paradigm. Ett objekt kan använda två databasfält tillsammans för att exponera en ny del av beräknad information. Värdena för de två enskilda fälten kan vara irrelevanta för applikationen och följaktligen dolda ur sikte.

SKAPA TABELLprodukter & # 40; Pris INTEGER, TaxRate INTEGER & # 41 ;; slutklass Produkt & # 123; & nbsp; offentlig funktion __construct & # 40; skyddad int $ Pris, skyddad int $ TaxRate & # 41; & # 123; & # 125; & nbsp; offentlig funktion getTotalPrice & # 40; & # 41; : int & # 123; returnera & # 40; $ detta – & gt; Pris * & # 40; $ detta – & gt; TaxRate/100 & # 41; & # 41 ;; & # 125; & # 125;

Applikationen bryr sig bara om det totala produktpriset inklusive skatter. Enhetspriset och skattesatsen inkapslas av produktklassen. Synlighetskontroller (skyddad) döljer värdena. Det offentliga gränssnittet består av en enda metod som använder de två fälten för att beräkna ett nytt värde.

Mer allmänt förespråkar objektorienterad programmering programmering till gränssnitt. Direkt tillgång till fastigheter avskräcks. Genom att använda klassmetoder som implementerar ett gränssnitt kan alternativa implementeringar konstrueras i framtiden.

Det finns ingen direkt motsvarighet till detta i den relationella världen. Databasvyer ger ett sätt att kombinera tabeller och abstrakta fält till nya former. Du arbetar dock fortfarande direkt med fältvärden.

Sammanfattning

Objektrelationella impedansfel matchningar uppstår när en objektorienterad kodbas utbyter data med en relation databas. Det finns grundläggande skillnader i hur data modelleras. Detta nödvändiggör införandet av ett kartläggningsskikt som överför data mellan formaten.

Problemet med impedansfel är en av de viktigaste motiverande faktorerna för antagandet av ORM inom objektorienterade språk. Dessa möjliggör automatisk hydrering av komplexa kodbasobjekt från relationsdatakällor. Utan ett dedikerat datakartningsskikt har bara de enklaste applikationerna en enkel väg till och från en relationsdatabas.