Mik azok a tervezési minták (design patterns)?

Mik azok a tervezési minták (design patterns)?
Tervezési minták a gyakorlatban

Nagyon sokszor hallok olyat, hogy egy fejlesztő nemhogy nem ismeri a tervezési mintak fogalmát, de még nem is hallott róla és egyenesen ellenkezik a hasznosságát illetően. Pedig az igazság az, hogy szoftvermérnökként, fejlesztői, architekt pozícióban ez nélkülözhetetlen. Sőt, nagyobb multi cégek nem is alkalmaznak ezen ismeretek hiányában.

Nagyon leegyszerűsítve azt lehet mondani, hogy egy átlagos programozótól az különböztet meg egy piacon értékes szoftverfejlesztőt, hogy tisztában van ezen tervezési minták használatával és gyakorlatával. Az ismeretek hiányában nagyobb cégek „spagetti” fejlesztőnek fognak minket titulálni, így mindenkit bíztatok arra, hogy ismerje meg most ezeket a tervezési mintákat.

A szoftvertervezési minták (design pattern) olyan újrafelhasználható megoldások, melyek gyakori problémákat oldanak meg. Nem konkrét kódot, implementációt kell érteni alatta, hanem úgymond egy útmutatót (paradigmát), mely az adott probléma megoldására bejáratott megoldási útvonal. Tehát a tervezési minták egy általános, újrafelhasználható megoldási eszköztár, melyet egy alkalmazás tervezésekor vethetünk be a minőségi megoldások kialakításához. Nem egy kész terv, implementáció, amely közvetlenül kóddá alakítható, hanem egy leírás vagy sablon egy probléma megoldásához, amely sokféle helyzetben használható.

Nézzünk gyorsan egy példát:
A villanyszerelőknél úgymond egy konvenció (de nem törvényszerű), hogy a fázisvezeték fekete színű. Ebből azonnal tudják a képzett villanyszerelők, hogy az adott vezetéket hova kell bekötni. Amikor viszont nincs jelölve a vezeték színe, akkor csak az az ember tudja, hogy melyik a fázisvezeték, aki legutóljára azon dolgozott. Ezzel nekünk plusz munkát hoz létre, mert kik kell mérnünk, hogy mely vezetik a fázis, a nulla.

A tervezési minták az objektum orientált programozás (OOP) támogatására szolgálnak, mely paradigma (útmutató) az objektumok (osztálypéldány) és az osztályok (adattípusok) koncepcióján alapul. Akik ismerik ezeket a koncepciókat, mintákat, sokkal könnyebben el tudnak igazodni egy ismeretlen kódbázison, hiszen nem kell kitalálni, hogy „mire is gondolt a költő eredetileg”.

Ebből az útmutatóból választ kapunk a tervezési minták hasznosságára, előnyeire, hátrányaira. Részletezzük a leggyakoribb tervezési mintákat.

Tervezési minták felhasználása

A tervezési minták felgyorsítják a fejlesztési folyamatot azáltal, hogy tesztelt, bevált fejlesztési paradigmákat biztosítanak. A hatékony szoftvertervezéshez olyan problémák mérlegelésére van szükség, amelyek csak később válnak láthatóvá a megvalósítás során. A tervezési minták újrafelhasználása segít megelőzni az olyan problémákat, amelyek komoly problémákat okozhatnak, és javítja a kód olvashatóságát a mintákat ismerő kódolók és architektek számára.

Az emberek gyakran csak azt értik, hogyan kell bizonyos szoftvertervezési technikákat bizonyos problémákra alkalmazni. Ezeket a technikákat nehéz a problémák szélesebb körére alkalmazni. A tervezési minták általános megoldásokat kínálnak, olyan formátumban dokumentálva, amely nem igényel konkrét problémához kötött konkrétumot.

Miért van szükségünk tervezési mintákra?

A tervezési minták a legjobb gyakorlati megközelítést kínálják az objektum orientált szoftvertervezés támogatására, amely könnyebben tervezhető, implementálható, módosítható, tesztelhető és újrafelhasználható. Ezek a tervezési minták a legjobb gyakorlatokat és struktúrákat biztosítják.

  1. Bevált megoldások
    A tervezési minták bevált, megbízható megoldást kínálnak egy gyakori problémára, ami azt jelenti, hogy a szoftverfejlesztőnek nem kell „újra feltalálnia a kereket”, amikor a probléma előfordul.
  2. Újrafelhasználható
    A tervezési minták sokféle probléma megoldására módosíthatók – nem csak egyetlen problémához kötődnek.
  3. Kifejező
    A tervezési minták alkalmazása az egyes implementációk során, áttekinthető, elegáns megoldást jelentenek.
  4. Kevesebb refactor
    Mivel a tervezési minta már az optimális megoldás a problémára, ezzel elkerülhető a refactorálás.
  5. Kódbázis méret csökkentés
    Mindegyik minta segít a szoftverfejlesztőknek megváltoztatni a rendszer működését teljes újratervezés nélkül. Továbbá, mint „optimális” megoldás, a tervezési minta gyakran kevesebb kódot igényel.

A tervezési minták előnyei a szoftverfejlesztésben

A szoftvertervezési minták egy közös nyelvet fognak használni, megkönnyítve a fejlesztők számára a problémákkal kapcsolatos kommunikációt, valamint a kód olvashatóságának és architektúrájának javítását a tervezés korai szakaszában.

Ha jól használjuk, a tervezési minták felgyorsíthatják a fejlesztési folyamatot és általában csökkenthetik a hibák esélyét.

Sokan megkérdőjelezik a hasznosságát, de miért?

A tervezési minták koncepcióját néhányan kritizálják az IT területén.

Rossz problémát céloz meg
A minták iránti igény a hiányos absztrakciós képességgel rendelkező programozási nyelvek használatából adódik. Néhányan azt állítják, hogy egy probléma megoldását nem lemásolni, hanem hivatkozni kell. De ha valamire hivatkoznak a másolás helyett, akkor nincs „minta” a címkézéshez és a katalogizáláshoz.

Hiányoznak a formális alapok
A tervezési minták tanulmányozása túlzottan ad hoc volt, és néhányan azzal érveltek, hogy a koncepciót sokkal formálisabb, szabályszerűbb alapokra kell helyezni.

Nem hatékony megoldásokhoz vezet
A tervezési minta ötlete a már elfogadott legjobb gyakorlatok szabványosítására tett kísérlet. Ez elvileg előnyösnek tűnhet, de a gyakorlatban gyakran a kód szükségtelen megkettőzéséhez vezet. Szinte mindig hatékonyabb megoldás egy jól átgondolt megvalósítás, nem pedig egy „csak alig elég jó” tervezési minta.

Nem különbözik lényegesen más absztrakcióktól
Egyes szerzők azt állítják, hogy a tervezési minták nem különböznek lényegesen az absztrakció más formáitól, és szükségtelen az új terminológia használata a programozás területén meglévő jelenségek leírására. A Modell-View-Controller paradigmát a „minta” példájaként hirdetik, amely több évvel megelőzi a „tervezési minták” fogalmát.

A tervezési mintákat 3 nagy csoportba soroljuk a nekik szánt feladatok szerint:

  1. Létrehozási tervezési minták – Creational design patterns
  2. Struktúrális tervezési minták – Structural design patterns
  3. Viselkedési tervezési minták – Behavioral design patterns

Létrehozási tervezési minták – Creational design patterns

A szoftverfejlesztésben a létrehozó tervezési minták olyan tervezési minták, amelyek valaminek a létrehozási mechanizmusával foglalkoznak és megpróbálnak az adott kontextusnak megfelelő objektumokat létrehozni.

Az objektumok szabadelvű létrehozása alapvető tervezési problémákat okozhatnak, vagy bonyolultabbá tehetik a tervezést. A létrehozó tervezési minták ezt a problémát úgy oldják meg, hogy valamilyen módon szabályozzák az objektum létrehozását, azt nem ad-hoc megalkotott szabályok alapján biztosítják.

Ezek a tervezési minták az osztály példányosításáról szólnak. Míg az osztály (class) létrehozási minták hatékonyan alkalmazzák az öröklődést a példányosítási folyamatban, az objektum (object) létrehozási minták hatékonyan használják a delegálást a munka elvégzéséhez.

Abstract factory minta

Létrehoz egy példányt több osztálycsoportból.
Pl.: egy bútorszett létrehozását reprezentáljuk: szék + kanapé + dohányzóasztal.
Ez a bútorszett több változatban is elérhető: modern, retro, victorian. Mindegyik változatban szükség lesz a következő műveletekre: székek létrehozása, kanapé létrehozása, dohányzóasztal létrehozása.

Builder minta

Elválasztja az objektumlétrehozást a reprezentációjától. Lépésről lépésre építi fel a szükséges objektumokat, a műveletek meghatározott sorrendjében.

Factory minta

Létrehoz egy példányt több származtatott osztályból. Interfészt biztosít az ősosztály objektumok létrehozására, ugyanakkor biztosítja a leszármazott osztályok számára, hogy módosítsák az ősosztály bizonyos viselkedéseit.

Prototype minta

Teljesen inicializált példány, amelyet másolni vagy klónozni kell.

Singleton minta

Osztály, amelynek csak egyetlen példánya létezhet.

Struktúrális tervezési minták – Structural design patterns

A szoftverfejlesztésben a strukturális tervezési minták olyan tervezési minták, amelyek megkönnyítik a tervezést az entitások közötti kapcsolatok megvalósításának egyszerű módjának azonosításával.

Adapter minta

Az inkompatibilis interfésszel rendelkező objektumok együttműködését biztosítja.

Bridge minta

Elválasztja az objektum absztrakcióját a megvalósítástól. Lehetővé teszi egy nagy osztály, vagy egymáshoz szorosan kapcsolódó osztályok felosztását két különálló hierarchiára: absztrakció és megvalósítás, melyek egymástól függetlenül fejleszthetők.

Composite minta (Object Tree)

Lehetővé teszi, hogy az objektumokat fastruktúrába állítsuk össze, majd ezekkel úgy dolgozhatunk, mintha egyetlen egyedi objektum lenne.

Decorator minta

Adott objektumhoz új viselkedés hozzárendelése úgy, hogy ezeket az objektumokat a viselkedést tartalmazó speciális burkoló objektumba helyezi.

Facade minta

Egyetlen osztály, amely egy teljes alrendszert, összetett osztálykészletet fog össze.

Flyweight minta

Több objektum között megosztja a közös állapotrészeket, ahelyett, hogy az összes adatot az egyes objektumokban tárolná.

Proxy minta

Lehetővé teszi egy másik objektum helyettesítését vagy helyőrzőjét. A proxy vezérli az eredeti objektumhoz való hozzáférést, lehetővé téve, hogy végrehajtson valamit, mielőtt vagy miután a kérés eljut az eredeti objektumhoz.

Viselkedési tervezési minták – Behavioral design patterns

Ezek a tervezési minták az osztályok objektumkommunikációjáról szólnak. A viselkedésminták azok a minták, amelyek leginkább az objektumok közötti kommunikációra vonatkoznak.

Azonosítják az objektumok közötti közös kommunikációs mintákat. Ezáltal ezek a minták növelik a kommunikáció rugalmasságát.

Chain of Responsibility minta

A felelősségi lánc lehetővé teszi, hogy kéréseket továbbítson a kezelők láncán. A kérés beérkezésekor minden kezelő eldönti, hogy feldolgozza-e a kérést, vagy továbbítja azt a lánc következő kezelőjének.

Command minta

A kérést önálló objektummá alakítja, amely tartalmazza a kéréssel kapcsolatos összes információt. Ez az átalakítás lehetővé teszi a kérések metódus argumentumként történő átadását, a kérés végrehajtásának késleltetését vagy sorba állítását, valamint a visszavonhatatlan műveletek támogatását.

Iterátor minta

Lehetővé teszi egy gyűjtemény elemeinek bejárását anélkül, hogy felfedné a mögöttes reprezentációját (lista, verem, fa stb.)

Mediator minta

Lehetővé teszi az objektumok közötti kaotikus függőségek csökkentését. A minta korlátozza az objektumok közötti közvetlen kommunikációt, és arra kényszeríti őket, hogy csak egy közvetítő objektumon keresztül működjenek együtt.

Memento minta

Lehetővé teszi egy objektum korábbi állapotának mentését és visszaállítását anélkül, hogy felfedné a megvalósítás részleteit.

Observer minta

Lehetővé teszi egy értesítési mechanizmus meghatározását, amely több objektumot értesít minden olyan eseményről, amely az általuk megfigyelt objektummal történik.

State minta

Lehetővé teszi az objektum viselkedésének megváltoztatását, ha belső állapota megváltozik. Úgy tűnik, mintha az objektum megváltoztatta volna az osztályát.

Strategy minta

Lehetővé teszi, hogy meghatározzon egy algoritmuscsaládot (műveletláncot), mindegyiket külön osztályba helyezze, és az objektumaikat felcserélhetővé tegye.

Template method minta

Meghatározza egy algoritmus vázát a szuperosztályban, de lehetővé teszi, hogy az alosztályok felülírják az algoritmus bizonyos lépéseit anélkül, hogy megváltoztatnák annak szerkezetét.

Visitor minta

Lehetővé teszi az algoritmusok elkülönítését azoktól az objektumoktól, amelyeken működnek.

A fenti tervezési minták közül a leggyakoribbakat példákkal és részletes leírásokkal ismertetjük a könnyebb érthetőség érdekében.