A mai történet egy esettanulmány arról, hogyan alkalmazzunk a tudást, amit a refactoring to patterns-ből tanultunk.
Azon az alkalmazáson, amin éppen (nem túl lelkesen) dolgozom tartalmaz egy igen súlyos bugot. Régen használt két eljárást. Rendszerint egyiket a másik után. A felhasználó oldaláról ez úgy nézett ki, hogy megnyomott két gombot egymás után.
A mostani verzió egyik új fejlesztése, hogy ezt a műveletet úgymond automatizálják, azaz automatikusan végrehajtódik egyik a másik után.
Igen ám, csak a másik eljárás úgy lett megírva hajdanán, hogy az első által adatbázisba írt adatokból dolgozik, és az alapján hajt végre műveleteket és értelemszerűen ír az adatbázisba. Szóval, ha az első eljárás eredményét használja, akkor A-t ír, ha a nélkül, akkor B-t.
A gond ott jelentkezik, hogy egymás után meghív egy tranzakcióban a második nem látja az első által adatbázisba írt értékét. Most értetlenkedni lehet, hogy miért nem, de aki ismeri az ABAP tranzakció-kezelő elveit annak ez akár normális lehet. Nekem nem az. Röviden arról van szó, hogy a SAP AS egy úgynevezett update taskot használ. Amikor egy update taskra dedikált eljárást hív, akkor az eljárás végrehajtását sorba helyezi. Maga a sorba elhelyezett eljárások a commit-ra hajtódnak végre, szépen sorban.
Mondjuk hasonló lenne akkor is az eset, ha olyan környezetben akarjuk használni a második eljárást, ahol nem akarunk adatbázisba írni, csak az eredményét akarjuk viszont látni.
Mondhatnánk nem a legrugalmasabb architektúra és igazunk is van. Ez egy úgynevezett ősrendszer. Megérett az átalakításra. Megjegyzem, nem tudom, hogyan sikerült (ha egyáltalán már sikerült) megoldani a problémát. Itt azt akarom leírni, hogy szerintem hogyan kellene.
- Első lépés egy úgynevezett Finder interfész létrehozása. Az interfész elrejti a második eljárás selektjét. Magyarán a select helyett egy eljáráshívás lesz.
- Két implementációt készítünk hozzá. Egy amolyan alapértelmezettet, ami tartalmazza a selectet és egy másikat, ami ebben a speciális esetben fogunk használni (pl. belső táblából véve az adatokat). A választást egy Factory fogja megoldani. A factory alapesetben az első implementációt adja. De mi a folyamat elején beállítjuk, hogy ebben az scennárióban a másikat adja. A folyamat végén persze visszaállítjuk.
- Módosítjuk az alkalmazást, hogy a Findert használja.
Mit nyerünk még ezzel a megoldással. Alig bonyolultabb, de sokkal rugalmasabb architektúrát. A jövőben például transzparensen tudunk cachelést bevezetni a programba. Más környezetben is tudjuk használni a komponensünket, hiszen az aktuális adatforrás akár futás időben lecserélhető.