Szerző: Budai Péter

2004. december 17. 12:18

Könyvajánló: Programtervezési minták

Az objektumorientált programozás tervezési módszereit összefoglaló első átfogó referencia 1995-ben jelent meg. A Kiskapu Kft. jóvoltából a szakkönyv immár magyarul is olvasható, ezáltal a programozást tanulók hatalmas segítséget kaptak, és immár pótolhatják azokat az ismereteket, amelyek szakmájuk gyakorlásához elengedhetetlenek.

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Programtervezési minták -- újrahasznosítható elemek objektumközpontú programokhoz, Kiskapu kft., 2004, 421 oldal, 5980 forint

Programozás elmélet
Felhasználói szint: haladó

Az objektumorientált programozás valódi alapjai

A szoftverfejlesztés fejlődésében jelentős mérföldkövet jelentett az objektumorientált megközelítés elterjedése. Igaz, hogy minden alkalmazás elkészíthető hagyományos procedurális, és objektumorientált eszközökkel is, de a korábbi technológiákkal mindez lényegesen több időt, energiát és szakértelmet igényelt, különösen nagyobb rendszerek esetében. Az objektumorientált tervezés és programozás (OOP) több általános problémára adott általános választ: segítségével a forráskód könnyedén modularizálható, a különválasztott kódrészletek egyszerűbben és biztonságosabban programozhatóak, a jól felépített osztályok és osztályhierarchiák könnyebben bővíthetőek, és akár újra is használhatóak egy eltérő probléma megoldására. Az OOP-nek hála ma már olyan méretű rendszerek is elkészíthetőek, amiket egyetlen ember, vagy akár fejlesztőcsoport is képtelen lenne átlátni.

Az OOP alapjainak elsajátítása nem igényel hatalmas időráfordítást, és a manapság elérhető programozási nyelvek mindegyike támogatja ezt a technológiát, még ha kicsit el is térnek egymástól -- a legtöbb nyelv saját megoldásokkal bővíti az OOP eszköztárát, de az alapelvek már több mint 15 éve változatlanok. Az OOP módszer használata során meg kell határozni a leprogramozandó rendszerben előforduló funkcionalitás közös pontjait, és el kell különíteni a szerteágazó szoftverrendszerek azon részeit, amelyek a rendszer többi részétől csak csekély mértékben függnek. Az ezáltal nyert, zárt modulokra bontott rendszer alkotóelemei külön-külön elkészíthetőek, akár anélkül, hogy a rendszer egészéről tudomásunk lenne. Egy modul fejlesztése szempontjából csak az a lényeges, hogy milyen funkcionalitást kell támogatnia, illetve hogyan kommunikál a külvilággal, és a többi modullal.

Mivel az OOP célja a tetszőleges méretű rendszerek fejlesztésének lehetővé tétele, illetve annak felgyorsítása, ezért célkitűzései között szerepel az is, hogy a hasonló működéssel vagy felépítéssel rendelkező forráskódrészleteket csak egyszer kelljen kifejleszteni. Ezáltal ha egy már meglévő forrásrészletre nagyban hasonlító kódra van szükség, akkor nem kell ugyanazt többször is megírnunk, helyette kiindulásként felhasználható a már meglévő implementáció. Az OOP eszközei tökéletesen alkalmasak arra, hogy bármilyen rendszer a forráskód szintjén modularizálható legyen általa, és a hasonló működési részeket tartalmazó elemeket közös nevezőre lehessen hozni. Hamar észrevehető, hogy a modularizálás, illetve a közös részek egységes megvalósítása a legtöbb esetben egymásnak ellentmond, ezért a program tervezése során meg kell találni az egyensúlyt a két alapvető szempont között. Az azonban gyakran problémát okoz a kezdő programozóknak, hogy az OOP általuk ismert valamennyi eszközével pontosan hogyan érhetik el ezeket a kitűzött célokat.


A magyar könyv borítója

Sajnálatos módon a mai programozóképzés gyakran megáll az OOP alapkoncepcióinak tárgyalásánál, és a nagyobb rendszerek hatékony programozásának problémáival nem kíván foglalkozni -- ezáltal a konkrét fejlesztési gyakorlattal nem rendelkező programozók hatalmas erőfeszítések árán készítik el alkalmazásaikat és rendszereiket első munkahelyükön, ami az első egy-két évben megfelelő mentor, vagy munkahelyi segítség nélkül nehezen bővíthető, és mások számára teljességgel átláthatatlan forráskód létrehozását eredményezi. Az OOP eszközeinek és alapfogalmainak ismerete (osztály, példány, öröklődés, többalakúság, egységbezárás, stb.) önmagában kevés, ha nem egészül ki megfelelő tervezéselméleti háttérrel vagy gyakorlattal. Sokan nem is értik, mire jó az OOP, hiszen nem láttak még nagy rendszereket fejlődni, és a rendelkezésükre álló tankönyvek és tanárok nem világítják meg a valódi célokat, hanem kizárólag az eszközökkel és egyszerű példákkal foglalkoznak.

Egy klasszikus alapmű magyar fordítása

Az objektumorientált programozás tervezési módszereit összefoglaló első átfogó referencia 1995-ben jelent meg angolul az Addison-Wesley kiadásában. A könyvet létrehozó szerzőcsapatot a legtöbben csak "a négyek" névvel illetik, ők azok, akik az 1991-ben megrendezésre került OOPSLA (Object-Oriented Programming, Systems, Languages & Applications) konferencián elsőként számoltak be a tervezési módszerek összefoglalására tett erőfeszítéseik eredményeiről. Az általuk összegyűjtött programtervezési minták az OOP eszközei segítségével adnak választ a programtervezés során felmerülő leggyakoribb kérdésekre, és a módszerek ismeretével a kevesebb gyakorlattal rendelkező programozók is kedvezőbb esélyekkel vághatnak bele egy nagy rendszer fejlesztésébe. A Kiskapu kft. 2004-ben jelentette meg a szakkönyv magyar változatát, ezáltal a Magyarországon programozást tanulók hatalmas segítséget kaptak, és immár -- önerőből -- pótolhatják azokat az ismereteket, amelyek szakmájuk megfelelő gyakorlásához elengedhetetlenek.

A könyv három részre osztható: az első rész általános bevezetőként szolgál, és bemutatja az OOP programozók gyakori hiányosságait, és igyekszik megoldást nyújtani rájuk. A második rész egy esettanulmány, ami egy elsőre talán egyszerűnek tűnő szövegszerkesztő alkalmazás kicsit sem egyszerű tervezési problémáival foglalkozik. A harmadik szekció pedig a programtervezési minták tényleges gyűjteménye, referenciája. A könyv leginkább C++ kódrészletekkel és UML-diagrammokkal támasztja alá az elméleti mondanivalót, de előfordul benne -- a manapság talán már ismeretlennek mondható -- Smalltalk nyelven írt programrészlet is. Mivel az OOP megvalósítása szinte valamennyi napjainkban használt programozási környezetben közel azonos, ezért a könyv nem csak C++ programozók számára nyújt segítséget, bár megköveteli a nyelv alapszintű ismeretét a példák megértéséhez.

A könyvben 23 tervezési minta részletes és igényes bemutatása található meg; a szerzők mindegyiknél megfogalmazzák a minta használatának céljait, feladatait, kiemelik felhasználhatóságának körülményeit, és kifejtik a minta használatának következményeit is -- ezáltal könnyen képet alkothatunk arról, hogy érdemes-e az adott mintát a programunkban alkalmazni, és az milyen előnyökkel, illetve hátrányokkal jár a rendszer egészére nézve. A mintákhoz minden esetben C++ példakódot is találnunk. A könyvben törekedtek arra is, hogy a mintákat együtt is képesek legyenek használni az olvasók, ezért a minták közti kapcsolatokról, és azok közös felhasználásáról is szó esik. A mintákról azt is megtudhatjuk, hogy milyen, már létező programrészekben kerültek felhasználásra -- ezek azonban nagy segítséget nem jelentenek, mivel többségük legalább tíz éve elavult, és a mai ember számára többnyire ismeretlenek, vagy teljesen érdektelenek.

A mintákat az írók a létrehozási, szerkezeti és viselkedési kategóriákba sorolták. A létrehozási minták az adott helyzetben megfelelő objektumpéldányok létrehozásának eszközeit mutatják be, a szerkezeti minták a bővíthetőség és az újrahasznosíthatóság figyelembevételével tesznek javaslatokat az osztályok konkrét felépítésére és azok együttes szervezésére, a viselkedési minták pedig arra nézve adnak tanácsokat, hogy hogyan érdemes a rendszer vezérlési folyamatait az objektumok szemszögéből megtervezni.

[oldal:Változásra tervezve]

Az esettanulmány a könyvben szereplő valamennyi tervezési mintát felhasználja, és megmutatja, hogy mire képes, illetve milyen nehézségekbe ütközik az OOP egy valódi, mindennap használt alkalmazás fejlesztése során. Ez a tanulmány rendkívül hasznos, és igazán gondolatébresztő, azonban kicsit bosszantó, hogy az objektumtervezésen túlmenően a felvetett problémákra a konkrét megvalósítás szintjén már nem nyújt segítséget -- de a könyvnek természetesen nem is célja a tervezésen túlmenően tanácsokat adnia.

A könyv az OOP tervezés elsődleges szempontjaként tárgyalja az újrahasznosításra való törekvést, valamint az osztályok elkülönítését oly módon, hogy a szoftverrel szembeni igények reálisan elképzelhető változásaira fel legyen készítve az architektúra. Ennek a hozzáállásnak köszönhetően egy szoftverfejlesztési projekt életciklusa során bekövetkező koncepcionális és funkcionális módosítások könnyebben kivitelezhetővé válnak az objektummodellben is. Ugyanez a személet figyelhető meg az esettanulmány kapcsán is, amelyben a szoftvert előre felkészítik a különféle operációs rendszerek és megjelenítési felületek támogatására.

Lépést kell tartani

Mivel az eredeti angol kiadás 1995-ben jelent meg, a könyv nem minden tekintetben felel meg a mai kor igényeinek: manapság a tervezési minták egyre inkább elszakadnak a szigorúan objektum orientált nézettől. Egyre szélesebb körben terjed a kódgenerálás, és kódszinkronizálás, mint az egyszerű fejlesztés eszköze -- elég csak a Microsoft .NET keretrendszer Windows Forms designerére, vagy a Delphi ablaktervezőjére gondolni, de manapság már az automatizálható fejlesztési feladatokhoz is érdemes lehet saját kódgeneráló programokat fejleszteni. Ezen kívül a modern programozási környezetek gyakran arra is lehetőséget adnak, hogy a hagyományos OOP osztályokat a megszokottól eltérő módon érhessük el, például enumerálhatjuk egy osztály példányának publikus metódusait, és meg is hívhatjuk azokat, valamint egyéb leíró tulajdonságokkal láthatjuk el az osztályok alkotóelemeit. Jó példa erre a Microsoft .NET keretrendszer System.Reflection és a System.CodeDOM névtere, amivel akár futásidőben, dinamikusan is létrehozhatóak teljesen új osztályok és azok példányai. Ugyancsak a kódgenerálást preferálja a Microsoft új kezdeményezése, ami magyarra fordítva "szoftvergyárak" névre hallgat -- erről egy későbbi cikkünkben számolunk be részletesen.

Mindettől függetlenül a könyvben szereplő minták mind a mai napig tökéletesen használhatóak, mindössze kiegészültek új tervezési és egyszerűsített kódgeneráló megoldásokkal.

Ami viszont továbbra is probléma a fejlesztéssel foglalkozó szakkönyvek esetében, az a nem egységes terminológia használata. Gyakorlatilag Magyarországon nincs még egy könyv, ami hasonló témát ilyen mélységig tárna föl, ezért az itt szereplő fogalmak és kifejezések magyarítása is a fordítók feladatát képezte. Ennek eredményeképpen szinte minden angol szó magyar megfelelőt kapott, ami az esetek túlnyomó többségében nagyon jól megközelíti az eredeti jelentést. Azonban azáltal, hogy a könyv olvasóközönségét alkotó fejlesztők többnyire angolul használják a mindennapi életben ezeket a kifejezéseket, és korábban is csak úgy találkoztak velük, az első pár órában nagyon zavaró a teljesen magyar terminológia olvasása -- ez azonban idővel megszokható. Az a kezdeményezés mindenesetre örömteli, hogy rá akarják bírni a magyar fejlesztőket az egységes magyar terminológia használatára. Viszont más kérdés, hogy érdemes-e a fejlesztőknek mindent két nyelven is ismerniük, hiszen a szakirodalom nagy része továbbra is csak angolul érhető el, és külföldi vagy multinacionális cégnél történő munkavégzés esetében is szerencsésebb a világszerte elfogadott angol kifejezések ismerete.

A könyv bevezetőjében tárgyalt OOP és tervezési alapelvek első -- de még néha második -- olvasásra nagyon nehezen érhetőek, részben a magyarított terminológiának, részben a nehézkés, nem annyira beszédes magyarázatnak köszönhetően. Arra senki se számítson hogy magát az OOP-t innen meg tudja tanulni, és akik még csak ismerkednek az OOP-val, azok ne ijedjenek meg, ha az ebben a részben tárgyalt témákat nem egészen értik. Sajnos a bevezető könnyen alkalmas arra is, hogy a magabiztos tudással még nem rendelkező fejlesztőket teljesen összezavarja. Ez a probléma szerencsére a könyv gerincét alkotó tartalmi fejezetekben -- így a minták bemutatásánál és az esettanulmány kapcsán -- már nem áll fenn.

Magyarországon egyetlen helyen végeznek a témával kapcsolatban képzést, amit a könyv szakmai lektora, Soczó Zsolt tart a Design Pattern tanfolyam képében a NetAcademiánál. A tanfolyam a könyv tartalmával azonos alapokon nyugszik, azonban érdemes kiemelni, hogy a tanfolyami anyag sem a magyarított, hanem az eredeti angol kifejezéseket használja, és bemutatja a kódgenerálás, valamint egyes fejlesztési minták megvalósítását is.

A tervezés nem csak ennyiből áll

Probléma, hogy a szoftverfejlesztéssel foglalkozó nagyvállalatok gyakran alapként várják el az OOP és a programtervezési minták gyakorlott használatát, azonban ezt kevés Magyarországon képzett pályakezdő ismeri a megfelelő mélységig. A nagy rendszerek tervezése nem áll meg az objektumosztályok tervezésénél, hiszen egész hálózatokon átívelő megoldások fejlesztése sokszor sokkal magasabb szintű absztrakciót igényel, mint amit egy programozó a mindennapi tevékenysége során korábban tapasztalt, és ezek többnyire a programtervezési mintákhoz hasonló elvekre épülnek. Azoknál a vállalatoknál, ahol a kezdő programozókra ilyen szintű tervezést bíznak, gyakran előfordul, hogy a projektek az előirányzott időre nem, vagy csak rossz minőségben készülnek el, illetve annak továbbfejlesztése és megváltoztatása nehézkés feladattá válik. Ennek elkerülésére érdemes nagy tapasztalattal rendelkező szoftver- és rendszertervezőkre bízni a tevékenységek ezen részét, és mielőbb ki kell képezni az új programozókat is arra, hogy képesek legyenek hatékonyan, változásra tervezve fejleszteni. Viszont ezt a mai oktatási rendszer kevésbé támogatja, így ez a könyv bármely fejlesztő számára hatékony segítséget jelenthet. Remélhetőleg a közeljövőben már az informatikai egyetemek és főiskolák óráin is találkozhatunk vele.

Azzal is érdemes tisztában lenni, hogy a szoftver- és rendszertervezés messze nem merül ki az OOP tervezésben, az gyakorlatilag csak egy kis szelete ennek a hatalmas tortának. Ahhoz, hogy jó minőségű programok és rendszerek szülessenek, szükséges a projektmenedzsment, az elosztott rendszerek tervezése, a kódolás és a tesztelés területéről is elsajátítani az elismert, bevált módszereket, mintákat, és azt sem szabad elfelejteni, hogy az elegáns tervezést sokszor felboríthatja az alkalmazás sebességének javítása, ezért minden tervezési lépésnél érdemes átgondolni, hogy az milyen hatással lesz a rendszer tényleges teljesítményére.

Gyakori probléma még, hogy a programtervezési mintákkal megismerkedő fejlesztőknek annyira megtetszik a témakör, hogy olyan területekre is alkalmazzák a megtanult módszereket, ahol azok kevéssé hatékonyak, és összességében több kárt okoznak használatukkal, mint amennyit nyernek vele. Ezeket a szakirodalom "anti-pattern"-eknek nevezi -- ez magyarul talán leginkább "nem javasolt minták"-ra fordítható. Ezeket az angol nyelvű Anti Pattern Catalog Wiki gyűjteményben is meg lehet tekinteni. Itt a meglévő tervezési minták gyakran mulatságos kifigurázásaira, illetve azok nem megfelelő használatára láthatunk példákat.

A könyvet a Kiskapu Kiadó bocsátotta rendelkezésünkre. Köszönet érte!

Véleménye van?

A kraftie a HWSW IT-karrierrel foglalkozó, immár sok tízezer IT szakembert mozgató meetup- és podcast-sorozata. Mostantól pedig már egy hírlevél is! Iratkozz fel Te is, ha szeretnél heti egyszer egy rövid, de értékes karrierfókuszú tartalmat kapni.

a címlapról