Dela via


Funktionell programmering jämfört med imperativ programmering (LINQ till XML)

Den här artikeln jämför och kontrasterar funktionell programmering med mer traditionell imperativ (procedurmässig) programmering.

Funktionell programmering kontra imperativ programmering

Det funktionella programmeringsparadigmet skapades uttryckligen för att stödja en ren funktionell metod för problemlösning. Funktionell programmering är en form av deklarativ programmering. Däremot utformades de flesta vanliga språk, inklusive objektorienterade programmeringsspråk (OOP), till exempel C#, Visual Basic, C++ och Java, för att främst stödja imperativ (procedurmässig) programmering.

Med en imperativ metod skriver en utvecklare kod som anger de steg som datorn måste vidta för att uppnå målet. Detta kallas ibland för algoritmisk programmering. En funktionell metod innebär däremot att skapa problemet som en uppsättning funktioner som ska köras. Du definierar noggrant indata för varje funktion och vad varje funktion returnerar. I följande tabell beskrivs några av de allmänna skillnaderna mellan dessa två metoder.

Characteristic Imperativ metod Funktionell metod
Programmerarens fokus Så här utför du uppgifter (algoritmer) och hur du spårar ändringar i tillstånd. Vilken information som önskas och vilka omvandlingar som krävs.
Tillståndsändringar Viktigt. Obefintlig.
Körningsordning Viktigt. Låg prioritet.
Primär flödeskontroll Loopar, villkorsstyrda och funktionsanrop (metod). Funktionsanrop, inklusive rekursion.
Primär manipulationsenhet Instanser av strukturer eller klasser. Fungerar som förstklassiga objekt och datasamlingar.

Även om de flesta språk har utformats för att stödja ett specifikt programmeringsparadigm är många allmänna språk tillräckligt flexibla för att stödja flera paradigm. De flesta språk som innehåller funktionspekare kan till exempel användas för att på ett trovärdigt sätt stödja funktionell programmering. Dessutom innehåller C# och Visual Basic explicita språktillägg för att stödja funktionell programmering, inklusive lambda-uttryck och typinferens. LINQ-teknik är en form av deklarativ, funktionell programmering.

Funktionell programmering med XSLT

Många XSLT-utvecklare är bekanta med den rena funktionella metoden. Det mest effektiva sättet att utveckla en XSLT-formatmall är att behandla varje mall som en isolerad, komposterbar transformering. Körningsordningen är helt framhävd. XSLT tillåter inte biverkningar (med undantag för att undvikande mekanismer för att köra procedurkod kan införa biverkningar som resulterar i funktionell orenhet). Men även om XSLT är ett effektivt verktyg är vissa av dess egenskaper inte optimala. Om du till exempel uttrycker programmeringskonstruktioner i XML blir koden relativt utförlig och därför svår att underhålla. Dessutom kan det stora beroendet av rekursion för flödeskontroll resultera i kod som är svår att läsa. Mer information om XSLT finns i XSLT-transformeringar.

XSLT har dock visat värdet av att använda en ren funktionell metod för att transformera XML från en form till en annan. Ren funktionell programmering med LINQ till XML liknar på många sätt XSLT. De programmeringskonstruktioner som LINQ introducerade till XML, C#och Visual Basic gör det dock möjligt att skriva rena funktionella transformeringar som är mer läsbara och underhållsbara än XSLT.

Fördelar med rena funktioner

Den främsta orsaken till att implementera funktionella transformeringar som rena funktioner är att rena funktioner är komposterbara: det vill säga fristående och tillståndslösa. Dessa egenskaper medför ett antal fördelar, inklusive följande:

  • Ökad läsbarhet och underhåll. Detta beror på att varje funktion är utformad för att utföra en specifik uppgift med tanke på dess argument. Funktionen förlitar sig inte på något externt tillstånd.
  • Enklare reiterativ utveckling. Eftersom koden är enklare att omstrukturera är det ofta enklare att implementera designändringar. Anta till exempel att du skriver en komplicerad transformering och sedan inser att viss kod upprepas flera gånger i omvandlingen. Om du omstrukturerar genom en ren metod kan du kalla din rena metod efter befallning utan att oroa dig för biverkningar.
  • Enklare testning och felsökning. Eftersom rena funktioner enklare kan testas isolerat kan du skriva testkod som anropar den rena funktionen med typiska värden, giltiga kantfall och ogiltiga gränsfall.

Av de skäl som beskrivs ovan passar funktionell programmering väl för arkitekturstilen för mikrotjänster.

Övergång för OOP-utvecklare

I traditionell objektorienterad programmering (OOP) är de flesta utvecklare vana vid programmering i imperativ/procedurmässig stil. För att byta till att utveckla i en ren funktionell stil måste de göra en övergång i sitt tänkande och sin syn på utveckling.

För att lösa problem designar OOP-utvecklare klasshierarkier, fokuserar på korrekt inkapsling och tänker när det gäller klasskontrakt. Beteendet och tillståndet för objekttyper är av största vikt, och språkfunktioner, till exempel klasser, gränssnitt, arv och polymorfism, tillhandahålls för att hantera dessa problem.

Funktionell programmering använder sig däremot av beräkningsproblem som en övning i utvärderingen av rena funktionella omvandlingar av datasamlingar. Funktionell programmering undviker tillstånd och föränderliga data och betonar i stället tillämpningen av funktioner.

Lyckligtvis kräver C# och Visual Basic inte hela steget till funktionell programmering, eftersom de stöder både imperativa och funktionella programmeringsmetoder. En utvecklare kan välja vilken metod som passar bäst för ett visst scenario. I själva verket kombinerar program ofta båda metoderna.

Se även