Moduláris programozás

A Wikipédiából, a szabad enciklopédiából

A moduláris programozás egy olyan szoftvertervezési technika, amely hangsúlyozza a program funkcionalitásának felosztását független, cserélhető modulokra úgy, hogy minden modul tartalmazza mindazt, ami szükséges a kívánt funkcionalitás egy aspektusának végrehajtásához.

A modul interfésze deklarálja azokat az elemeket, amelyeket a modul biztosít vagy igényel. Ezek az elemek érzékelhetők más modulok által. Az implementáció tartalmazza a működő kódot, amely megfelel az interfészben meghatározott elemeknek. A moduláris programozás szorosan kapcsolódik a strukturált programozáshoz és az objektumorientált programozáshoz, mindannyian ugyanannak a célkitűzésnek a megvalósítására törekednek, hogy a nagy szoftverprogramok és rendszerek kialakítását kisebb részekre bontsák, és mind az 1960-as években születtek. Bár ezeknek a kifejezéseknek a történelmi használata nem volt következetes, a moduláris programozás jelenleg már az egész program kódjának magas szintű felbontására utal: a strukturált programozás a strukturált vezérlési folyamaton alapuló alacsony szintű kódhasználatra, míg az objektumorientált programozás az objektumok (egyfajta adatszerkezet) használatára vonatkozik.

Az objektumorientált programozásban interfész-alapú programozásnak nevezik az interfészek architekturális mintaként való használatát a modulok felépítéséhez.

Történelem[szerkesztés]

Alrendszerek (különösen az I/O-val kapcsolatosak) és szoftverkönyvtárak formájában a moduláris programozás már az első szoftverrendszerekben jelen volt, ahol kód-újrafelhasználásra használták. Maga a moduláris programozás, meghatározott céljával, az 1960-as és 1970-es években fejlődött ki, mint a strukturált programozás koncepciójának nagyobb méretű analógja (1960-as évek). A moduláris programozás kifejezés a Larry Constantine által 1968-ban a Information and Systems Institute-ban szervezett Moduláris Programozásról szóló Nemzeti Szimpóziumra (National Symposium on Modular Programming) vezethető vissza. Más kulcsfontosságú fogalmak voltak az információ elrejtése (information hiding, 1972) és a vonatkozások szétválasztása (Separation of Concerns, 1974).

A modulok eredetileg nem szerepeltek az ALGOL 68 eredeti specifikációjában (1968), de kiterjesztésként hozzáadták őket az az ALGOL 68-R (1970) és az ALGOL 68C (1970) implementációkhoz, majd hivatalosan is rögzítették őket. Az egyik első moduláris programozásra tervezett nyelv a rövid életű Modula (1975) volt, amelyet Niklaus Wirth fejlesztett. Egy másik korai moduláris nyelv a Xerox PARC által kifejlesztett Mesa volt (1970-es évek), és Wirth az eredeti Modula mellett ebből is merített a Modula-2 (1978) fejlesztésekor, amely hatással volt későbbi nyelvekre, különösen az utódjára, a Modula-3-ra (1980-as évek). A Modula vezette be a pont-kvalifikált jelölést, mint például az M.a az M modul a objektumára való hivatkozást jelenti, hasonlóan a rekordok mezőinek vagy az objektumok attribútumaihoz és metódusaihoz eléréséhez használt jelöléssel, és ma már széles körben elterjedt, például a C#, Dart, Go, Java, OCaml és Python nyelvekben. A moduláris programozás az 1980-as évektől vált széles körben elterjedtté: az eredeti Pascal nyelv (1970) még nem tartalmazott modulokat, de a későbbi verziók, különösen az UCSD Pascal (1978), a Turbo Pascal (1983), és a Pascal által befolyásolt Ada (1980) bevezették ún. egységek (units) formájában. Az Extended Pascal ISO 10206:1990 szabványa közelebb állt a Modula-2-höz a moduláris támogatás szempontjából. A Standard ML (1984) rendelkezett az egyik legteljesebb modulrendszerrel, beleértve a funktorokat (paraméterezhető modulokat), amelyek lehetővé tették a modulok közötti leképzést.

Az 1980-as és 1990-es években a moduláris programozás háttérbe szorult, és gyakran összemosódott az objektumorientált programozással, különösen a C++ és a Java népszerűsége miatt. Például a C nyelvcsalád támogatta az objektumokat és osztályokat a C++ (eredetileg C with Classes, 1980) és az Objective-C (1983) nyelvekben, de a modulok támogatására csak 30 évvel később került sor. A Java (1995) ún. csomagok (packages) formájában támogatja a modulokat, bár a kód szervezésének alapvető egysége az osztály. Azonban a Python (1991) már a kezdetektől fogva hangsúlyosan használt mind modulokat, mind objektumokat, a modulokat pedig a kód szervezésének fő egységének tekintette, míg a csomagokat nagyobb méretű egységként kezelte. A Perl 5 (1994) támogatta mind a modulokat, mind az objektumokat, és számos modul érhető el a CPAN (1993) kiterjesztett Perl archívumban. Az OCaml (1996) az ML nyelvet követve támogatja a modulokat és funktorokat.

A moduláris programozás jelenleg széles körben elterjedt, és megtalálható gyakorlatilag minden, az 1990-es évek óta kifejlesztett jelentős nyelvben. A modulok relatív fontossága eltérő lehet a nyelvek között, és az osztályalapú objektumorientált nyelvekben továbbra is fennáll az átfedés és a zavar a modulok és az osztályok között, mint szervezési és egységbe zárási egységek, de mindkettő jól meghatározott és különálló fogalom.

Terminológia[szerkesztés]

A modul elnevezés helyett a .NET nyelvekben (mint például a C#, F# vagy Visual Basic .NET) használják a kódkönyvtár (assembly) vagy csomag (package) kifejezéseket is. Más implementációkban ezek különböző fogalmak; például a Pythonban a csomag modulok gyűjteménye, míg a Java 9-ben új modulfogalom (csomagok gyűjteménye, továbbfejlesztett hozzáférés-szabályozással) került bevezetésre.

Ezen felül, a "csomag" kifejezést a szoftverekben másképpen is használják (például .NET NuGet csomagok). A komponens hasonló fogalom, de jellemzően magasabb szintre utal; a komponens egy egész rendszer egy darabja, míg a modul egy egyedi program egy darabja. A modul fogalmának skálája jelentős mértékben változik a nyelvek között; a Pythonban nagyon kis léptékű, minden egyes fájl egy modul, míg a Java 9-ben nagy léptékűnek tervezik, ahol egy modul csomagok gyűjteménye, amelyek viszont fájlok gyűjteményei.

A modulokra vonatkozó egyéb kifejezések közé tartozik a Pascal dialektusokban használt unit (egység).

Nyelvi támogatás[szerkesztés]

A modul koncepciót formálisan támogató nyelvek közé tartozik az Ada, Algol, C++, C#, Clojure, COBOL, Common Lisp, D, Dart, eC, Erlang, F#, Fortran, Go, Haskell IBM Assembly és Control Language, IBM RPG, Java,[1] JavaScript,[2] Julia, MATLAB, ML, Modula, Modula-2, Modula-3, Morpho, Objective-C, OCaml, a Pascal számos származéka (Component Pascal, Object Pascal, Turbo Pascal, UCSD Pascal), Perl, PHP, PL/I, PureBasic, Python, R, Ruby,[3] Rust.

Szembetűnő példák a modulok támogatását nélkülöző nyelvekre a C, C++, Pascal korai változatai. Azonban a C és C++ lehetővé teszik a különálló kompilációt és a deklaratív interfészek megadását header fájlok segítségével. A modulokat hozzáadták az Objective-C-hez az iOS 7-tel (2013), a C++-hoz a C++20-szal, a Pascalt pedig a Modula és Oberon váltotta fel, amelyek már kezdetektől fogva tartalmaztak modulokat, valamint modulokat tartalmazó különböző leszármazott nyelvek. A JavaScript már az ECMAScript (2015) óta rendelkezik natív modulokkal.

Moduláris programozás végrehajtható akkor is, ha a programozási nyelv nem biztosít explicit szintaktikai eszközöket nevesített modulok támogatására, például C nyelv esetén. Ezt meglévő nyelvi jellemzők felhasználásával történik, kiegészítve például kódolási konvenciókkal, programozási idiómákkal és a kód struktúrájával. Az IBM i is használ modulokat az Integrált Nyelvi Környezetben (ILE) történő programozás során.

Kulcsfontosságú szempontok[szerkesztés]

A moduláris programozás lehetővé teszi az alkalmazások strukturáltabbá tételét és az egységes felelősségi körök elkülönítését. A modulok között jól definiált interfészek biztosítják a kommunikációt, és a modulok függőségi gráfja segítségével könnyen átláthatóvá válik a kód egészének szerkezete és működése. A hierarchikus felépítés lehetővé teszi a kódbázis modularitásának és újrafelhasználhatóságának maximalizálását, valamint a fejlesztési folyamat hatékonyságának növelését.

Moduláris rendszer létrehozásakor monolitikus alkalmazás létrehozása helyett (ahol a legkisebb komponens az egész), hanem több kisebb modult írnak külön-külön, és ezekből áll össze a futtatható alkalmazásprogram. Általában ezek a modulok külön-külön kerülnek fordításra, majd egy linker segítségével összekapcsoltatnak. Egy just-in-time fordító a konstrukció néhány részét akár futásidőben is létrehozhatja.

Ezeket a független funkciókat általában a programvezérlő funkciók vagy a speciális feladatfunkciók közé sorolják. A programvezérlő funkciókat úgy tervezték, hogy egy adott programhoz működjenek. A specifikus feladatfüggvények úgy vannak előkészítve, hogy különböző programokhoz legyenek alkalmazhatóak.

Ezáltal a modulárisan tervezett rendszerek, ha helyesen épülnek fel, sokkal jobban újrafelhasználhatóvá válnak, mint a hagyományos monolitikus tervezés, mivel az összes (vagy sok) ilyen modul változtatás nélkül újra felhasználható más projektekben. Ez megkönnyíti a projektek több kisebb projektre való felbontását. Elméletileg egy modularizált szoftverprojektet könnyebben összeállíthatnak nagy csapatok, mivel a csapat egyetlen tagja sem alkotja meg az egész rendszert, sőt nem is kell ismernie a rendszer egészét. Csak a kijelölt kisebb feladatra koncentrálhatnak.

Jegyzetek[szerkesztés]

  1. A csomag kifejezést a modulok analógiájára használják a JLS-ben, ld. James Gosling, Bill Joy, Guy Steele, Gilad Bracha, The Java Language Specification, Third Edition, ISBN 0-321-24678-0, 2005. A Bevezetésben a következő áll: „A 7. fejezet a program felépítését írja le, amely a Modula moduljaihoz hasonlóan csomagokba szerveződik. A modul szónak a Javában nincs különösebb jelentése. A Java modulokat a csomagok egyfajta gyűjteményét a Java 9-re tervezik a Project Jigsaw részeként; ezeket korábban szupercsomagoknak nevezték és a Java 7-re tervezték.
  2. ECMAScript® 2015 Language Specification, 15.2 Modules
  3. Class: Module (Ruby 2.0.0)

Fordítás[szerkesztés]

Ez a szócikk részben vagy egészben a Modular programming című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

További információk[szerkesztés]

Kapcsolódó szócikkek[szerkesztés]