A szoftverfejlesztési elvek olyan konkrét szabályok és ajánlások összessége, amelyeket a mérnököknek követniük kell a program megvalósítása során, ha szép, világos és karbantartható kódot akarnak írni. Nincs varázspálca, amely a változók, osztályok és függvények összevisszaságát tökéletes kóddá változtatná, de van néhány tipp és tanács, amelyek segítségével a mérnök megállapíthatja, hogy helyesen cselekszik-e.
Vessünk egy pillantást ezekre az alapvető ajánlásokra. Az alábbi elvek közül néhány Python-specifikus, de a legtöbb nem.
Kétszer mérj, egyszer vágj
Azt hiszem, ez a legfontosabb elv mind közül. Ha csak egyetlen elvet tanulsz meg ebből a bejegyzésből, az ez legyen. Mi, fejlesztők/architektek/menedzserek emberek küzdünk a figyelemhiánnyal, hülye hibákkal és elírásokkal, személyes problémákkal, rossz hangulattal és hideg kávéval. Mindezek egyike sem lényeges – a problémát meg kell oldani. Számomra, mint mérnök számára ez az elv azt jelenti, hogy a probléma megfelelő megoldásának kiválasztása, a probléma megfelelő megközelítésének kiválasztása, a megfelelő eszközök kiválasztása a probléma megoldásához, bizalom a megépített megoldás iránt. A választás itt azt jelenti, hogy át kell gondolni, meg kell találni a szükséges erőforrásokat, össze kell állítani a megfelelő csapatot, át kell gondolni a tervezést, át kell gondolni a megközelítést, feladatokat kell kitűzni, ellenőrizni kell az eredményt, és felelősséget kell vállalni érte. Ez a “mérnöki munka úgy, ahogy van”. Azt hiszem, én magam nem vagyok kész arra, hogy ezt korrekt szavakkal leírjam.
Ne ismételd magad (DRY)
Ez egy meglehetősen egyszerű, de nagyon hasznos elv, amely azt mondja, hogy ugyanazt a dolgot különböző helyeken megismételni rossz ötlet. Először is a kód további támogatásának és módosításának szükségességével függ össze. Ha egy programon belül valamilyen kódrészletet több helyen is megismétlünk, akkor nagy a valószínűsége két katasztrofális helyzetnek:
- A forráskód akár csak kis változtatásakor is több helyen kell ugyanazt a kódot módosítani. Ez további időt, erőfeszítést és figyelmet igényel(gyakran nem könnyű).
- Az első tétel követi a másodikat. Ön vagy egy másik fejlesztő a csapatából véletlenül kihagyhatja az egyik módosítást(ez megtörténhet egyszerűen az ágak összevonásával a vcs-ben), és szembesülhet az alkalmazás későbbi hibáival. Ezek a hibák frusztrálóak lehetnek az Ön számára, mert azt hallotta, hogy egy ilyen hibát már kijavítottak.
Ezzel kapcsolatban van egy ajánlás – ha egy kód több mint kétszer szerepel a listában, akkor azt külön kell elhelyezni. Ez egy általános ajánlás. Valójában akkor is érdemes elgondolkodni egy külön metódus létrehozásán, ha egy ismétlődéssel másodszor is találkozunk.
Occam borotvája
Ez egy nagyon elterjedt gondolat, amely a filozófiából érkezett a programozásba. Az elv William of Oakham angol szerzetesről kapta a nevét. Ez az elv kimondja: “Az entitásokat nem szabad szükség nélkül megsokszorozni”. A mérnöki gyakorlatban ezt az elvet a következőképpen értelmezik: szükségtelenül nem szabad felesleges entitásokat létrehozni. Ezért mindig érdemes először átgondolni, hogy milyen előnyökkel jár egy újabb módszer/osztály/eszköz/folyamat stb. hozzáadása. Végül is, ha egy újabb módszert/osztályt/eszközt/folyamatot stb. adunk hozzá, és a megnövekedett bonyolultságon kívül semmi más előnye nincs, akkor mi értelme?
Keep It Simple Stupid (KISS)
Ez egy nagyon hasonló elv a fentihez, de kissé más jelentése van. Ez az elv azt mondja ki, hogy a kódnak a lehető legegyszerűbbnek kell lennie, bonyolult struktúrák nélkül, különben megnehezíti a hibakeresést és a kód karbantartását. Emellett egy másik programozó számára nehezebb lesz megérteni a kód logikáját, ami viszont szintén több időt és erőfeszítést igényel. Ezért mindig olyan egyszerű konstrukciók használatára kell törekedni, amelyek a lehető legjobban megoldják a problémát, számos elágazás, mély egymásba ágyazás és túlzottan túlterhelt osztályszerkezetek nélkül. Ezzel megkönnyíted magad és a kollégáid életét, mert a komplexitás hibákat generál. Emlékezz arra, amit Peter Hintiens mondott: “Az egyszerűség mindig jobb, mint a funkcionalitás.”
Nem lesz rá szükséged (YAGNI)
Egy probléma, amitől sok programozó szenved. A vágy, hogy egyszerre minden szükséges (és néha még szükségtelen) funkcionalitást megvalósítsanak a projekt legelején. Vagyis amikor a fejlesztő az összes lehetséges metódust rögtön az elején hozzáadja az osztályához és implementálja, és lehet, hogy a későbbiekben soha nem is használja őket. Az ajánlás szerint tehát először csak azt valósítsuk meg, amire szükségünk van, és később, ha szükséges, bővítsük ki a funkcionalitást. Így fáradságot, időt és idegeket takaríthat meg a valójában nem szükséges kód hibakeresésével.”
Nagy tervezés előre
A funkcionalitás fejlesztésének megkezdése előtt először gondolja át az alkalmazás architektúráját, és tervezze meg az egész rendszert kellően apró részletekig, és csak ezután folytassa a megvalósítást egy előre meghatározott terv szerint. Az elvnek van létjogosultsága, de az utóbbi időben elég sok kritika érte. Ez mindenekelőtt a terv elavultságával függ össze a tervezés és a kidolgozás során. Ezzel kapcsolatban még mindig szükség van a későbbi változtatásokra. De vannak tagadhatatlan előnyei is, helyes tervezésnél jelentősen csökkenthetők a további hibakeresés és hibajavítás költségei. Emellett az ilyen információs rendszerek általában lakonikusabbak és építészetileg helyesebbek.”
Kerüljük az idő előtti optimalizálást
“Az idő előtti optimalizálás minden rossz (vagy legalábbis a legtöbb) gyökere a programozásban” – Donald Knuth
Az optimalizálás nagyon helyes és szükséges folyamat a program gyorsításához, valamint a rendszer erőforrás-fogyasztásának csökkentéséhez. De mindennek megvan a maga ideje. Ha az optimalizálást a fejlesztés korai szakaszában végzik, akkor többet árthat, mint használ. Ez először is azzal függ össze, hogy egy optimalizált kód kifejlesztése több időt és erőfeszítést igényel a fejlesztés és a támogatás során. Ebben az esetben elég gyakran kell először ellenőrizni a választott fejlesztési megközelítés helyességét. Ezért eleinte kifizetődőbb egy egyszerű, de nem a legoptimálisabb megközelítést használni. Később pedig, amikor megbecsüljük, hogy ez a megközelítés mennyire lassítja az alkalmazás munkáját, lépjünk át egy gyorsabb vagy kevésbé erőforrás-igényes algoritmusra. Ráadásul mindaddig, amíg kezdetben a legoptimálisabb algoritmust valósítja meg, a követelmények változhatnak, és a kód a szemétbe kerül. Nem kell tehát időt pazarolni az idő előtti optimalizálásra.
A legkisebb meghökkenés elve
Ez az elv azt jelenti, hogy a kódodnak intuitívnak és nyilvánvalónak kell lennie, és nem szabad meglepnie egy másik fejlesztőt a kód áttekintésekor. Ha például a metódus neve “sütik készítése”, de eredményként krumplit kapsz, akkor az a kód (nyilvánvalóan) rossz. Emellett meg kell próbálnod elkerülni a mellékhatásokat, és dokumentálnod kell őket, ha nem tudod elkerülni.
S.O.L.I.D.
A “SOLID” tulajdonképpen egy csoport objektumorientált tervezési elv. A “SOLID” minden egyes betűje az elvek egyikét jelöli, amelyek a következők:
- Az egyetlen felelősség azt jelenti, hogy minden modul vagy osztály a szoftver által biztosított funkcionalitás egyetlen részéért felel, és ezt a felelősséget az osztálynak teljes egészében be kell zárnia;
- A nyitott-zárt azt jelenti, hogy a szoftver entitások (osztályok, modulok, függvények stb.) nyitottnak kell lennie a bővítésre, de zártnak a módosításra;
- Liskov helyettesítés azt állítja, hogy az örökölt osztálynak ki kell egészítenie, nem pedig helyettesítenie kell az alaposztály viselkedését;
- interfész elkülönítés azt állítja, hogy egyetlen ügyfelet sem szabad arra kényszeríteni, hogy olyan metódusoktól függjön, amelyeket nem használ;
függőségi inverzió azt mondja, hogy a programozónak az interfész szintjén kell dolgoznia, nem pedig az implementáció szintjén.
Ezek az elvek együttesen alkalmazva segítenek a fejlesztőnek olyan kódot létrehozni, amely idővel könnyen karbantartható és bővíthető.
Demeter törvénye
Az alapelv lényege, hogy a felelősségi köröket fel kell osztani az osztályok között, és a logikát egy osztályon, metóduson vagy struktúrán belül kell kapszulázni. Ebből az elvből több ajánlás különböztethető meg:
- Az osztályok vagy entitások legyenek függetlenek
- A különböző osztályok közötti kapcsolatok számának csökkentésére kell törekedni (ún. csatolás).
- A kapcsolódó osztályoknak egy modulban/csomagban/könyvtárban kell lenniük (más néven kohézió).
Az említett elveket követve az alkalmazás rugalmasabbá, érthetőbbé és könnyen karbantarthatóvá válik.
Következtetés
Elfejlesztőtársak legyünk mérnökök! Gondolkodjunk a tervezésről és építsünk robusztus és jól megvalósított rendszereket, ahelyett, hogy organikus szörnyetegeket növesztenénk. A felsorolt elvek nagymértékben korrelálnak és lényegükben összefüggnek. Természetesen nem én alkottam meg őket, de egy kis emlékeztető nem árt, legalábbis az én memóriám biztosan nem tökéletes.
Javasolt könyvek
- Clean Code by Robert C. Martin
- Clean Architecture by Robert C. Martin