Dr. Iszály György Barna
Számítógépes program, vagy programok halmaza, mely kiegészül kiegészül a használatát lehetővé tevő dokumentációkkal, konfigurációs adatokkal, információs webhelyekkel. Egy termék - valamilyen hasznos célt kell kiszolgálnia, elő kell állítani, az előállítási folyamatnak költségei és időkorlátai vannak, ezért a felhasználó hajlandó fizetni érte, cserébe valamilyen minőséget vár el A szoftvernek azonban a más ipari termékektől eltérő tulajdonságai is vannak: Nem anyagi jellegű. Létezik ugyan tárgyiasult formája, de az nem más, mint adathordozók és dokumentációk halmaza. Nincsenek egyedi példányai. Egy szoftvert lemásolhatunk tetszőleges példányban, de ezek a másolatok teljes mértékben egyenértékűek az eredetivel. Ennek következménye, hogy előállítása nem igényli a tervezés sorozatgyártás fázisokat. Tükröznie kell a valóságot, de nem fizikai törvények vonatkoznak rá. Bonyolultsága (komplexitása) a legtöbb ipari terméket messze meghaladja. Ezeket a speciális tulajdonságokat kell figyelembe venni, ha a szoftver előállításának technológiáját vizsgáljuk.
Az IEEE szervezet 1983-as definíciója szerint: The technological and managerial discipline concerned with systematic production and maintenance of software products that are develop and modified on time and within cost estimated. Technológiai és vezetési alapelvek, amelyek lehetővé teszik programok termékszerű gyártását és karbantartását a költség- és határidő korlátok betartásával. Egyértelműen mérnöki tevékenységnek minősíti a szoftver előállítását: a gyártási folyamatot (általában szigorú) idő- és költség korlátok betartása mellett kell lebonyolítani!
Probléma, kérés, ötlet ( a megrendelőtől ) A felvetés értelmezése, pontos megfogalmazása, feladattá alakítása Döntés arról, hogy érdemes-e programot írni A program megírásához használható erőforrásaink számbavétele (hardver, szoftver) A feladat megoldásához szükséges INPUT (bemenő) adatok számbavétele Az OUTPUT (kimeneti) információk tartalmának és formájának megtervezése (képernyő és nyomtatási kép) A megoldás lépésről lépésre történő megadása ( az algoritmus megtervezése) Az algoritmus leírása (folyamatábra, struktogram, leírás, pszeudokód) A programnyelv kiválasztása Az algoritmus lekódolása ( a program megírása ) A program tesztelése (próbaadatokkal történő kipróbálása) A dokumentáció elkészítése Esetleg árualakra hozás
Követelmények megfogalmazása - funkcionális specifikáció Rendszertervezés (design) - rendszerterv Kódolás, testreszabás, tesztelés és dokumentálás Bevezetés
Megbízhatóság Ha egy programot megfelelően terveztünk meg, akkor elvileg megfelelően kell működnie Költségek A jó terv lecsökkenti az idő-, és ezáltal költségigényes, tesztelési fázist Karbantartás A jól megtervezett programot egyszerűbb módosítani
1. Vízesésmodell 2. Evolúciós vagy iteratív fejlesztés 3. Komponens alapú fejlesztés
Követelmények elemzése és meghozása: a rendszer szolgáltatásai, megszorításai és célja a rendszer felhasználóival történő konzultáció alapján alakul ki. Ezeket később részletesen kifejtik, és ezek szolgáltatják a rendszer specifikációt. Rendszer- és szoftvertervezés: szét választódnak a hardver- és szoftverkövetelmények. Itt alakítjuk ki a rendszer átfogó architektúráját. A szoftver tervezése az alapvető szoftverrendszer-absztrakciók, illetve a közöttük levő kapcsolatok azonosítását és leírását is magában foglalja. Implementáció és egységteszt: a szoftverterv programok, illetve programegységek halmazaként realizálódik. Az egységteszt azt ellenőrzi, hogy minden egység megfelel-e a specifikációjának. Integráció és rendszerteszt: a különálló programegységek, illetve programok integrálása és teljes rendszerként való tesztelése, hogy a rendszer megfelel-e a követelményeknek. Ez után a szoftverrendszer átadható az ügyfélnek. Működtetés és karbantartás: általában ez a leghosszabb fázis. Megtörtént a rendszertelepítés és megtörtént a rendszer gyakorlati használatbavétele. A karbantartásba beletartozik az olyan hibák javítása, amelyekre nem derült fény az életciklus korábbi szakaszaiban, a rendszeregységek implementációjának továbbfejlesztése, valamint a rendszer szolgáltatásainak továbbfejlesztése a felmerülő új követelményeknek megfelelően.
A fázisok eredménye egy dokumentum. A következő fázis addig nem indulhat el, amíg az előző fázis be nem fejeződött. A gyakorlatban persze ezek a szakaszok kissé átfedhetik egymást. Maga a szoftverfolyamat nem egyszerű lineáris modell, hanem a fejlesztési tevékenységek iterációjának sorozata. Ez a vízesésmodellnél a visszacsatolásokban jelenik meg. Probléma: a projekt szakaszainak különálló részekké történő nem flexibilis partícionálása. Egy komplex, bonyolult probléma megoldása nem végezhető el hatékonyan ezzel a megközelítéssel. Csak akkor használható jól, ha már előre jól ismerjük a követelményeket, melyeket részletes és pontos specifikáció követ.
A fejlesztőcsapat kifejleszt egy kezdeti implementációt, majd azt a felhasználókkal véleményezteti Addig finomítják, amíg a megfelelő rendszert el nem érik. Ez sokkal inkább érvényesíti a tevékenységek közötti párhuzamosságot és a gyors visszacsatolásokat. Két típusát különböztetik meg: Feltáró fejlesztés: célja egy működőképes rendszer átadása a végfelhasználóknak. Ezért elsősorban a legjobban megértett és előtérbe helyezett követelményekkel kezdik a fejlesztés menetét. Ennek érdekében a megrendelővel együtt tárjuk fel a követelményeket, és alakítják ki a végleges rendszert, amely úgy alakul ki, hogy egyre több, az ügyfél által kért tulajdonságot társítunk a már meglévőkhöz. A kevésbé fontos és körvonalazatlanabb követelmények akkor kerülnek megvalósításra, amikor a felhasználók kérik. Eldobható prototípus készítés: a fejlesztés célja ekkor az, hogy a lehető legjobban megértsük az ügyfél követelményeit, amelyekre alapozva pontosan definiáljuk azokat. A prototípusnak pedig azon részekre kell koncentrálni, amelyek kevésbé érthetők.
Két probléma: A folyamat nem látható: a menedzsereknek rendszeresen szükségük van leszállítható részeredményekre, hogy mérhessék a fejlődést. A rendszerek gyakran szegényesen strukturáltak: a folyamatos változtatások lerontják a rendszer struktúráját, így kevésbé érthetővé válik. A szoftver változásainak összevonása pedig egyre nehezebbé és költségesebbé válhat. A várhatóan rövid élettartalmú kis vagy közepes rendszerek esetén célszerű az alkalmazása Max. 500.000 programsorig Hosszú élettartalmú rendszerek esetén az evolúciós fejlesztés válságossá válhat pontosan az evolúciós jellege miatt.
Az újrafelhasználás-orientált megközelítési mód nagymértékben az elérhető újrafelhasználható szoftverkomponensekre, illetve azok egységes szerkezetbe történő integrációjára támaszkodik. Az eddigiektől eltérő fázisok a következőek: Komponenselemzés: az adott követelményspecifikációnak megfelelően megkeressük azon komponenseket, amelyek megvalósítják azok funkcióit, implementálták azokat. A legtöbb esetben nincs egzakt illeszkedés, a felhasznált komponens a funkciók csak egy részét nyújtja. Követelménymódosítás: a fázisban a megtalált komponensek információit felhasználva elemezzük a követelményeket, majd módosítani kell azokat az elérhető komponenseknek megfelelően. Ahol nem lehetséges a követelmény módosítása, ott újra el kell végezni a komponenselemzést és alternatív megoldást kell keresni. Rendszertervezés újrafelhasználással: ebben a szakaszban a rendszer szerkezetének tervezését hajtjuk végre. A tervezés kulcseleme az, hogy milyen komponenseket akarunk újrafelhasználni, és úgy alakítani a szerkezetet, hogy azok működhessenek. Amennyiben nincs elérhető újrafelhasználható komponens, akkor új szoftverek is kifejleszthetők. Fejlesztés és integráció: a nem megvásárolt, illetve átalakításra kerülő komponenseket ki kell fejleszteni és a rendszerbe integrálni. A rendszer-integráció ebben a modellben sokkal inkább tekinthető a fejlesztési folyamat részének, mint különálló tevékenységnek.
Előnye: csökkenti a kifejlesztendő szoftverek számát a komponensek újrafelhasználásával közvetve a költségeket redukálja Redukálja a felmerülő kockázati tényezőket Így gyorsabban is leszállítható a megrendelőnek a program. Hátránya: a követelményeknél elkerülhetetlenek a kompromisszumok az elkészült rendszer nem felel meg a megrendelő valódi kívánságainak.
A szoftverfolyamatot nem tevékenységek és közöttük található esetleg visszalépések sorozataként tekinti, hanem inkább egy spirálként reprezentálja A spirál minden egyes körben a szoftverfolyamat egyegy fázisát reprezentálja Tetszőleges számú kör, mint iteráció tehető meg A körök: Legbelső kör - a megvalósíthatósággal foglalkozik Következő kör - a rendszer követelményeinek meghatározásával foglalkozik Ezt következő kör - a rendszer tervezésével foglalkozik Stb.
A spirál minden egyes ciklusát négy fő szektorra oszlik: Célok kijelölése: az adott projektfázis által kitűzött célok meghatározása. Azonosítani kell a folyamat megszorításait, a terméket, fel kell vázolni a kapcsolódó menedzselési tervet. Fel kell ismerni a projekt kockázati tényezőit, és azoktól függően alternatív stratégiákat kell tervezni ha lehetséges. Kockázat becslése: minden egyes felismert kockázati tényező esetén részletes elemzésre kerül sor. Lépéseket kell tenni a kockázat csökkentése érdekében. Fejlesztés és validálás: a kockázat kiértékelése után egy fejlesztési modellt kell választani a problémának megfelelően. Pl. evolúciós, vízesés, stb modellek. Tervezés: A folyamat azon fázisa, amikor dönteni kell arról, hogy folytatódjon-e egy következő ciklussal, vagy sem. Ha a folytatás mellett döntünk, akkor fel kell vázolni a projekt következő fázisát.
Specifikáció: a feladat pontos meghatározása Tervezés: hogyan kell megoldani a feladatot? Kódolás: adott programozási nyelven megírt program Tesztelés: jó vagy rossz a program? Hibakeresés, -javítás: hol a hiba? teszteléshez vissza helyes program Hatékonyság vizsgálat: minőségvizsgálat és javítás jó program Dokumentálás: felhasználói, fejlesztői használható program (Karbantartás: a változó igényeknek megfelelő fejlesztések időtálló program)
a programkészítés folyamatának első lépése a feladat pontos meghatározása olyan leképezést (programfüggvényt) határoz meg, amely a bemenő értékekhez hozzárendeli a jó eredményt. a feladat szöveges és formalizált, matematikai leírásán túl tartalmazza a megoldással szemben támasztott követelményeket, környezeti igényeket is. Absztrakt specifikáció: Elő-, utófeltételek: A bemenő-, illetve a kimenő adatokra kirótt feltételek.
Feladatspecifikáció: 1. feladat szövege 2. a bemenő és kimenő adatok elnevezése, értékhalmazának leírása (vagyis az állapottér meghatározása) 3. a feladat szövegében használt fogalmak definíciói, eredmény kiszámítási szabálya 4. a bemenő adatokra meghatározott előfeltételek 5. a kimenő adatokra meghatározott utófeltételek A program specifikálása: 1. program elő- és utófeltétele 2. a bemenő és a kimenő adatok elnevezése, értékhalmazának leírása
1. a feladat szövegében használt fogalmak definíciói 2. a program környezetének leírása: hardver-, memória- és perifériaigény, programozási nyelv, szükséges fájlok stb. 3. a programmal szembeni egyéb követelmények: minőség, hatékonyság, hordozhatóság stb. Követelmények a specifikációval szemben: (szöveges vagy formális specifikációval szemben egyaránt) egyértelmű, pontos, teljes rövid, tömör, formalizált szemléletes, érthető
Egy mezőn N ló és M szekér található. Az i. ló ereje p i, az i. szekér súlya g i. Egy ló maximum egy szekeret húzhat, de ennek a súlya kisebb vagy egyenlő a ló erejével. Követelmény Határozzuk meg a lehetséges legnagyobb ló-szekér párt úgy, hogy a párban szereplő ló legyen képes húzni a megfelelő szekeret. Bemeneti adatok A lovak.in bemeneti állomány első sorában N + 1 természetes szám található: N p 1 p 2... p N, egy-egy szóközzel elválasztva, a fenti szövegben leírt jelentésekkel. A második sorban, hasonlóan, M + 1 természetes szám található: M g 1 g 2... g M, egy-egy szóközzel elválasztva.
Kimeneti adatok A lovak.out kimeneti állományba egyetlen számot írunk, a kért legnagyobb lehetséges ló-szekér párok számát. Megszorítások és pontosítások 1 N, M 10 000 1 p i < 2 15, i = 1,2,...,N 1 g i < 2 15, i = 1,2,...,M A tesztek 50%-ban M, N 1000 Példa lovak.in 6 3 3 4 4 5 1 6 3 4 5 2 1 6 lovak.out Magyarázat 5 A párok (ló indexe, szekér indexe): (1, 1), (2, 4), (3, 2), (5, 3), (6, 5). Maximális végrehajtási idő/teszt: 0.1 mp/teszt Rendelkezésre álló memória: 16 Mb
A leendő program szerkezetének megalkotása A program elemeinek megfelelő sorrendben való összerakása A szerkezetnek több szintje lehet átfogó szerkezet: függvények, eljárások, alprogramok finomszerkezet: változók, műveletek (utasítássorok, ciklusok, döntési szerkezetek) Elkülönül a kódírástól (kódolástól)
A probléma meghatározása, felmérése: specifikáció Részei: Bemeneti adatok: értékhalmaz, méret + tulajdonságok, korlátozó tényezők (előfeltételek) Eredmények (tulajdonságok, a megoldással szembeni követelmények) (utófeltételek) Tulajdonságai: Egyértelmű, pontos, teljes Rövid, tömör, formalizált Szemléletes, érthető
Algoritmustervezés Eszközei: algoritmusleíró eszközök Folyamatábra Struktogram Leírás mondatszerű elemekkel (pszeudokód) Paradigmaválasztás strukturált? objektumorientált? funkcionális? stb.
Stratégiai elvek: a feladatot néhány részfeladatra bontjuk lépésenkénti finomítás felülről lefelé való kifejtés: először átfogóan oldjuk meg a feladatot, majd a részfeladatokat addig finomítjuk, amíg olyan utasítások szintjéig nem érünk, amelyeket a gép már végre tud hajtani (piramis-elv) alulról felfelé való építés: a piramist fordítva építjük fel
párhuzamos finomítás elve: egy adott szint minden részfeladatát finomítjuk, nem szaladunk előre egy könnyűnek vélt ágon döntések elhalasztásának elve: célszerű minél későbbre halasztani azokat a döntéseket, amelyek a gép ill. a programnyelv adottságainak kihasználási módját jelentenék vissza az ősökhöz elv: ha zsákutcába kerülünk, vissza kell lépni az előző szintre
adatok leszigetelésének elve: az egyes programrészeken belül alkalmazott adatokat ne vigyük be más programrészletbe. (Paraméterekkel és lokális változókkal dolgozunk) párhuzamos ágak függetlenségének elve: egy szinten lévő eljárások egymást nem hívhatják, egymás változóit nem használhatják szintenkénti teljes kifejtés elve: a szint leírásának tartalmaznia kell az alatta levő szint eljárásainak specifikációját.
algoritmus leírási szabályok: kevés, de egyértelmű szabályt kell kialakítani. A fő programeszközök (szekvencia, ciklus, elágazás) jól különüljenek el. világos tagolás: csak a szervesen összefüggő utasítások kerüljenek egy sorba bekezdéses leírás (indentálás): az algoritmus szintekre tagolását a leírás formája is tükrözze összetett struktúrák zárójelezése: ciklus, elágazás, eljárás elejének és végének jelölése (C++: { }, Pascal, Delphi: begin end) beszédes azonosítók elve: az azonosító utal arra, hogy mire használjuk
barátságosság, udvariasság: tájékoztatás, segítségnyújtás biztonságosság: a felhasználói hibalehetőségekre fel kell készíteni a programot, és lehetőséget adni a javításra jól olvasható program: minél kisebb programegységek jól dokumentált program: kommentek
lapkezelési technika: egyszerre egy képernyőnyi információt jelenítünk meg, (egy sor ne legyen szélesebb, mint a képernyő), lapozás biztosítása, nyomtatásban lapszámozás, fejléc, lábléc menütechnika: felhasználóval való párbeszéd biztosítása kényelmes formában ikontechnika: grafikus kis ábrák szemléletesebbek lehetnek a szöveges megjelenítésnél értelmezési tartomány kijelzése: beolvasáskor jelezzük az értéktartományt és a mértékegységet fontos adatok kiemelése: időigényes feladatvégzés során küldjünk üzenetet a felhasználónak, hogy a program éppen hol tart
tördelés: a megjelenő szövegben a sorok, szavak tördelése a helyesírás szabályainak megfeleljen következetesség: beolvasáskor, kiíráskor hibajelzés: írjuk ki a hiba okát, adjunk instrukciót a javításra, legyen visszaállítható a hiba előtti képernyő naplózás: a fontos események automatikusan íródjanak fájlba makrók, funkcióbillentyűk: gyors eléréshez bizonyos funkciókhoz rendeljünk billentyűkombinációt segítség: bárhonnan legyen elérhető (- funkcióbillentyűvel) ablaktechnika: az ablakok a képernyő elkülönített részein jelennek meg, ablak: keret+tartalom
Hol helyezkedhetnek el a program futásához szükséges adatok? Háttértáron: fájlkezelés Operatív tárban (memória, RAM) A memóriában elhelyezkedő adatok kezelése Ha egy adat nem változik a program futása során: állandó, konstans (ha többször használjuk, érdemes nevet adni neki) Ami változik a futás során: változó
A feladat követelményeinek és a feldolgozandó adathalmazoknak függvényében: Statikus adatszerkezetek: tömb, struktúra (rekord), halmaz Félstatikus adatszerkezetek: verem, várakozási sor, hasító tábla Dinamikus adatszerkezetek: lista, fa, gráf
Az algoritmus implementálása: leírás programozási nyelven a fejlesztői dokumentáció alapján szétosztják a tervet minden programozó teszteli a saját munkáját összerakják a részeket rendszertesztelés Felhasználói dokumentáció
A strukturált programozás jelenti valamennyi ma használatos programtervezési módszer alapját Ma: a strukturált programozás a programfejlesztés egyetlen lehetséges módja a nagy problémát kisebb részfeladatok halmazára bontjuk, és a megoldást a részfeladatok megoldásával kezdjük alkalmazzuk a lépésenkénti finomítás elvét: a megoldandó feladatot részfeladatokra bontjuk úgy, hogy önmagukban megoldhatók legyenek az összes részfeladat megoldása után, az eredeti feladat megoldása a megfelelő illesztésekre korlátozódik
A goto utasítás használata kerülendő A strukturált programozás gyakran a felülről lefelé történő elvonatkoztatást, tervezést is jelenti Több szint, egymásba ágyazás. Az algoritmus alprogramokra (részekre) bontása Böhm, Jacopini: bármely program megírható pusztán az alapstruktúrák használatával A program karbantarthatóságának biztosításához elengedhetetlenül szükséges a strukturált programozás
Minden építőelemnek csak egy belépési, illetve kilépési pontja van Egy sem tartalmaz háromnál több alapelemet A belépési pont az algoritmuselemek elején, a kilépési pont a végén található
1. Szekvencia: utasítások sorba rakása Tetszőleges utasítások egymás után írt csoportja. Pl. értékadás, eljárás meghívása, beolvasás, kiírás A szekvencia végrehajtásának hatása: a sorban egymás után való utasítások végrehajtásának hatása. 2. Elágazás (szelekció) Egy programozási nyelvben akkor beszélünk elágazásról, mikor a vezérlés valamilyen feltételtől függően más-más ágon folytatódik. Ez a vezérlési szerkezet jól használható programfutás közbeni események vizsgálatára.
3. Ciklus (iteráció, ismétlő struktúra) A ciklus, vagy iteráció az ismétlődő (azonos vagy hasonló) tevékenységek megvalósítására szolgál. A ciklusok három alaptípusba sorolhatók aszerint, hogy hányszor futnak le: elöltesztelő, hátultesztelő és számlálós ciklus.
A program tetszőleges helyére (címkére) ugró utasítás: Goto. A számlálós ciklus megszakítását eredményező Break típusú eljárások Eljárásból kiugró Exit típusú vezérlési utasítások A programot befejező, Halt típusú utasítások Ezek használata veszélyes, a program strukturáltságát bontják, áttekinthetősége leromlik.
Bohm, Jacopini: a goto utasítás segítségével megírt bármely program megírható pusztán a strukturált programozás alapelemeinek használatával is A strukturált programozás, mint módszer általánosan elfogadott, de nincs vizsgálat, bizonyíték arra, hogy hatékonyabb, jobb A program karbantarthatóságát vizsgáló kísérletek a strukturált programozás melletti eredménnyel zárultak Vessey, Weber: a strukturál programozás használhatóságát alátámasztó érvek meglehetősen gyengék (megbízható kísérletek hiánya)
Világos írásmód és kifejezőerő...... címke:...... if a > 0 goto címke......... while a > 0 do...... endwhile... A bal oldali kódot felülről lefelé olvasva nem világos, hogy mi a címke szerepe, sőt több goto utasítás is ugorhat ugyanezen címkére. A goto több, egymástól lényegesen különböző cél megvalósítására is használható (elágazás, ciklus, ciklusból való kilépés, eljáráshívás), ezért kicsi a kifejezőereje. Világosabb kódot kapunk, ha a megfelelő egyedi nyelvi elemet használjuk. Könnyebb a programok helyességének bizonyítása (minden programelemnek csak egy belépési, ill. kilépési pontja van).
A goto is része a programozási nyelvek eszközkészletének, ha megtiltjuk a használatát, a programozó elől elvesszük a lehetőséget, hogy értelmesen felhasználja. Hibakezelés (a programegység belsejéből egy hibakezelő rutinra ugorhatunk, így az egységnek több kilépési pontja lesz). Növelhető a teljesítmény Néha kifejezetten természetes a goto használata (Donald Knuth: lazább megkötés a strukturált programozásra)
Algoritmus: olyan megengedett lépésekből álló módszer, utasítássorozat, részletes útmutatás, recept, amely valamely felmerült probléma megoldására alkalmas. Megengedett lépések ismerete általában feltesszük az elemi lépésekről, hogy: függetlenek, egyik sem állítható össze például néhány más lépés egymásutánjaként; relevánsak, azaz mindegyik lépés legalább egyszeri végrehajtása valóban szükséges a probléma megoldásához; teljes rendszert alkotnak, azaz a probléma megoldásához szükséges valamennyi elemi lépést felsoroltuk.
1. Az eljárás egyértelműen leírható véges szöveggel. 2. Az eljárás minden lépése ténylegesen kivitelezhető. 3. Az eljárás minden időpontban véges sok tárat használ. 4. Az eljárás véges sok lépésből áll. Az algoritmus fogalmát gyakorlatban a következőkre korlátozzák: Egy (determinisztikus) algoritmus ugyanarra a bemenetre mindig ugyanazt az eredményt adja Minden időpontban egyértelműen adott a következő lépés. A nem determinisztikus algoritmusok véletlenszámgenerátort alkalmaznak, így nem érvényes az első tulajdonság.
Mondatszerű leírás. informális jellegű leírás felsoroljuk a lépéseket, esetleg számozzuk a lépéseket ugrás: beleírjuk hova kell lépni ugrásokkal mindig meg lehet oldani a vezérlési struktúrákat (feltétel, ciklus) példa: Eukleidész algoritmusa két szám legnagyobb közös osztójának kiszámítására (legyen a két szám: a, b) 1. felírjuk a nagyobb számot a következő alakban a = b * q + r 2. ha a felbontásban r = 0, akkor q a legnagyobb közös osztó 3. ha r 0 akkor ( a, b ) = ( b, r ) és visszaugrunk az 1 lépésre
A folyamatábra (flowchart) segítségével a program dinamikus viselkedését, folyamatát részletekbe menően ábrázoljuk. Tevékenység-csomópont: téglalap Döntés-csomópont: az F feltételtől függően a vezérlés az igaz vagy a hamis ágon folytatódik. Gyűjtő-csomópont: A nyilak az algoritmus végrehajtása során összefuthatnak. Részletezés: A részletezéssel jelölt tevékenység egy külön folyamatábrán kerül kifejtésre. Program eleje és program vége Adatbevitel és adatkiírás Növekményes ciklus
Nassi-Shneiderman diagram (NSD), a strukturált programozást tükrözi, nincs lehetőség ugró utasításokra. A vezérlő szerkezetek a következőek: szekvencia elágazások ciklusok
álkód, ( majdnem kód) mivel ennek a leírási módnak egyetlen programozási nyelvvel sem azonos a formája. Az emberi nyelvhez közel álló, szabályokkal kötött mondatszerű leírás. A szabályok bizonytalanok, belekeveredhetnek programnyelvi elemek pl., a Pascal vagy a C++ nyelvek elemeiből.
Alapvető szabályok : 1. Az algoritmus blokkszerkezetét elsősorban a tagolás tükrözi. 2. A változók neve betűvel kezdődik. A változók típusát külön nem deklaráljuk, 3. A változók értékadó utasításokkal kapnak értéket. 4. Ciklusszervező utasítások: Amíg, Ismételd és Minden 5. Feltételes utasítás 6. A bevitel/kivitel a Ki és Be utasításokkal történik. 7. Eljárások, függvények hívása 8. A megjegyzések általában // jellel kezdődnek és az adott sor végéig tartanak vagy {} jelek közé íródnak.
Lépésenkénti finomítás Ez a tervezési módszer a megírandó program által végrehajtott műveletekre összpontosít. 1. A feladat szövegének megfogalmazása 2. Bemeneti, kimeneti adatok beazonosítása, esetleges adatszerkezetek kiválasztása 3. Megszorítások tisztázása 4. Megoldási modellek kiválasztása 5. Egyszerűen (magyarul) leírjuk azt a műveletsort, amit a programnak végre kell majd hajtania 6. Ezután a műveleteket fokozatosan finomítjuk, míg el nem érjük a kellő részletezettséget - a műveletek már a használni kívánt programnyelv elemeivel is leírhatók
A funkcionális felbontás módszere Dijkstra és Wirth nevéhez fűződik Az 1960-as években a strukturált programozással párhuzamosan fejlődött Felülről lefelé építkező tervezési módszer A funkcionális felbontás, mint tervezési módszer, elsősorban a program által végzett műveletekre összpontosít, így olyan területeken alkalmazható elsősorban, ahol ezek a műveletek egyértelműek, és központi szerepet töltenek be. A funkcionális felbontás támaszkodik a tervező fantáziájára és szakmai képességeire. Tág teret ad a kreativitásnak (ez lehet gyengeség is).
Pattogó labdát ütögetve egy falat kell lebontanunk szöveges képernyőn A képernyőt egy tömbön keresztül kezeljük ke: array[1..50,1..80,1..2]of char A labda koordinátáit az xlabda és ylabda tárolja.
videojáték rajzold meg az oldalfalakat rajzold meg az ütőt a kezdőpozícióban while akar valaki játszani do rajzold meg a falat játszd a játékot jelenítsd meg a legjobb eredményt endwhile A konkrét részleteket itt még általános utasítások fedik el, mely lehetővé teszi, hogy tanulmányozzuk, módosítsuk a tervet anélkül, hogy az apróbb részletekkel kellene törődnünk. Például észrevesszük, hogy hiányzik még a legjobb eredmény kezelése
videojáték rajzold meg az oldalfalakat rajzold meg az ütőt a kezdőpozícióban legjobb eredmény := 0 while akar valaki játszani do eredmény := 0 rajzold meg a falat játszd a játékot if eredmény > legjobb eredmény then legjobb eredmény := eredmény endif jelenítsd meg a legjobb eredményt endwhile
Ha az eredmény ezen a szinten már kielégítő, nekiállhatunk az egyes lépések részletesebb kidolgozásának Vegyük a játszd a játékot eljárást: játszd a játékot maradék labdák := 4 while maradék labdák > 0 do játssz a labdával csökkentsd eggyel a maradék labdák számát endwhile Megjelent egy újabb eljárás ( játssz a labdával ), melyet illik részletesebben is leírni
játssz a labdával rajzolj egy új labdát while a labda játékban van do vizsgáld meg a labda helyzetét mozgasd a labdát mozgasd az ütőt endwhile töröld a labdát a képernyőről Készítsük még el a ciklus három eljárásának részletezését
vizsgáld meg a labda helyzetét ellenőrizd, hogy játékban van-e még a labda ellenőrizd, hogy eltalálta-e a határfalak valamelyikét ellenőrizd, hogy eltalálta-e az ütőt ellenőrizd, hogy nekiütközött-e egy téglának ellenőrizd, hogy eltalálta-e az határfalak valamelyikét if a labda bármelyik oldafalnál van then XLépés := - XLépés endif if a labda a felső határon van then YLépés := - YLépés endif ellenőrizd, hogy nekiütközött-e egy téglának if ke[ylabda+ylépés, XLabda+XLépés] egy tégla helye then ke[ylabda+ylépés, XLabda+XLépés] := üres növeld az eredményt eggyel YLépés := -YLépés vonj le egyet a maradék téglák számából if maradék téglák száma = 0 then rajzolj falat endif endif
mozgasd a labdát töröld a labdát a régi helyén XLabda := XLabda + XLépés YLabda := YLabda + YLépés ke[ylabda, XLabda, 1] := "o mozgasd az ütőt if billentyű = "q" then mozdulj balra endif if billentyű = "w" then mozdulj jobbra endif mozdulj balra töröld az ütőt if ütő helyzete > bal oldali fal + 1 then ütő helyzete := ütő helyzete 1 endif rajzold meg az ütőt
A lépésenkénti finomítás egy folyamat, amely az algoritmus kezdetleges vázának elkészítésétől a végleges kidolgozott algoritmusig tart. Ahhoz, hogy a tervezés bármely szintjén megértsük a rendszer működését, nem kell pontosan ismernünk az alacsonyabb szintek működését. Tudnunk kell, hogy az alacsonyabb szintek mit csinálnak, de azt nem, hogy hogyan. Két út: szintről-szintre történő finomítás (breadth first) egy ágnak a lehető legnagyobb részletességgel való kifejtése (depth first) A pszeudokód minden részletét a strukturált programozás szabályainak betartásával írjuk le.
Egy program logikai szerkezete egyértelműen előállítható az általa kezelt vagy előállított adatok szerkezete alapján. Pl: A bemenetről érkező pozitív számokat adjuk össze. A számsort egy negatív szám zár le. 4 6 12 5-22 A bemenő adatokban ismétlődés tapasztalható, így a programban is lennie kell egy ismétlődő szakasznak. Tehát a bemenő adatok szerkezetéből kiindulva vontunk le egy, a program szerkezetére vonatkozó következtetést.
Példa: Rajzolja ki a program a következő ábrát a karakteres képernyőre: * *** ***** ***** *** * Kép Felső fél Közép Alsó fél Első lépés: az adatszerkezet elemzése adatszerkezet-diagram Vonal * Vonal * A rajzolandó ábra egy felső részből, egy középső kihagyásból és egy alsó részből áll A felső és az alsó rész is ismétlődő sorokat tartalmaz
Tartalmaz : A tartalmazza B-t A B Ismétlés: A objektum 0 vagy több B objektum sorozata Sorozat: A valójában egy B és egy C sorozata A A B * B C
Az adatszerkezetet a logikai felépítésben felülről lefelé haladva (egyre finomítva) írjuk le. Az adatszerkezet elkészítése után a következő lépés annak programszerkezetté történő át-alakítása A programszerkezetnek pontosan tükröznie kell a feldolgozni kívánt adatok szerkezetét, ezért ez viszonylag könnyű Programszerkezeti diagram
Kép feldolgozása Felső fél feldolgozása Közép feldolgozása Alsó fél feldolgozása Vonal feldolgozása A diagram értelmezése: * * Vonal feldolgozása A program mint egész (a diagram legfelső doboza) tartalmazza (vonalak a dobozok között) bizonyos utasítások egy sorozatát (egy szinten elhelyezkedő dobozok) Egyes programösszetevőket néha ismételten is végre kell hajtani (csillag a doboz sarkában)
A következő lépés, hogy tetszőleges sorrendben leírjuk mindazokat az elemi műveleteket, amelyeket a programnak végre kell hajtania (ez a legkevésbé meghatározott eleme ennek a tervezési módszernek) A példánkban a lista az alábbi műveleteket tartalmazza: 1. n darab csillag nyomtatása 2. üres sor nyomtatása 3. s darab szóköz nyomtatása 4. s növelése 5. s csökkentése 6. n növelése 7. n csökkentése 8. n és s kezdeti beállítása
Kép feldolgozása 8 Felső fél feldolgozása Közép feldolgozása Alsó fél feldolgozása 8 Vonal feldolgozása 1 3 6 5 * * 2 Vonal feldolgozása 1 3 7 4 1. n darab csillag nyomtatása 2. üres sor nyomtatása 3. s darab szóköz nyomtatása 4. s növelése 5. s csökkentése 6. n növelése 7. n csökkentése 8. n és s kezdeti beállítása
n és s beállítása while vannak még sorok do s darab szóköz kinyomtatása n darab csillag kinyomtatása s csökkentése n növelése endwhile üres sor nyomtatása n és s beállítása while vannak még sorok do s darab szóköz kinyomtatása n darab csillag kinyomtatása s növelése n csökkentése endwhile
Felrajzoljuk a feldolgozandó adatok szerkezetét ábrázoló diagramot Elkészítjük az ennek megfelelő programszerkezet-diagramot Leírjuk azoknak az elemi műveleteknek a listáját, amelyeket a programnak végre kell hajtani Elhelyezzük ezeket a műveleteket a program szerkezetét leíró diagramban Előállítjuk a program vázlatos logikai szerkezetét
A feladat: Adjunk össze egy számsorozatot, melynek a végét egy negatív szám jelzi!
Adatszerkezet-diagram Számok Programszerkezet-diagram az elemi műveletekkel Számok feldolgozása Törzs Negatív szám 3 Törzs feldolgozása Negatív szám feldolgozása Szám * 1. szám beolvasása 2. szám hozzáadása az összeghez 3. az összeg kezdeti beállítása 4. az összeg kiíratása 1 2 Szám feldolgozása * 4
Átalakítás pszeudokóddá: összeg := 0 while a szám nem negatív do a szám beolvasása a szám hozzáadása az összeghez endwhile a szám kiírása A logikai szerkezet felírása a diagram alapján mechanikusan történt, nem tökéletes. A Jackson tervezési módszer csak a program logikai vázát segít megadni, a finomabb részletek kidolgozásában nem segít. A kód helyesen: összeg := 0 a szám beolvasása while a szám nem negatív do a szám hozzáadása az összeghez a szám beolvasása endwhile a szám kiírása
Feladat: Egy soros elérésű fájl személyek rekordjait tartalmazza. Számoljuk meg, hogy a lista hány férfit és hány nőt tartalmaz!
Adatszerkezet-diagram Pszeudokód Törzs * Bejegyzés Fájl Fájlvége fájl megnyitása számlálók beállítása while a fájlnak nincs vége do egy bejegyzés olvasása if bejegyzés = férfi then férfiak számlálójának növelése else nők számlálójának növelése endif endwhile a számlálók értékének kiírása a fájl bezárása Férfi Nő Látható, hogy az alternatívákra utaló, -rel jelölt dobozok if then else szerkezetként jelennek meg a kódban
A Jackson tervezési módszer alapelve szerint egy program logikai felépítését alapvetően az határozza meg, hogy milyen adatokat akarunk vele feldolgozni. A napjainkban használatos módszerek közül valószínűleg a legrendszerezettebb, jól elkülöníthető lépések sorozatából áll. Nem támaszkodik a programozó megérzéseire (viszont kreativitást igényel) Néhány könnyen átlátható alapelvre épít (strukturált programozás, az adatszerkezet és a feldolgozó program szerkezete közötti szoros kapcsolat) Könnyen tanítható Következetes (egy adott feladatnál két ember valószínűleg ugyanarra fog jutni) Egyszerű, könnyen használható Programozási nyelv független
Alkalmazhatóság Jackson szerint általánosan alkalmazható A szakirodalom leginkább adatok (fájlok) soros feldolgozásával (kötegelt adatfeldolgozás) kapcsolatos problémákat említ Nehezen elképzelhető például az alkalmazása egy szám négyzet-gyökét fokozatos közelítéssel kiszámító program esetén, hiszen a be- és kimenő adatok szerkezetéből (mindkettő egy-egy szám) nem lehet következtetéseket levonni a program szerkezetével kapcsolatban. Kisebb programok tervezésére (ahol még nem kerülnek előtérbe az objektumorientált módszerek) Szerepe Újabban divatossá vált alábecsülni a módszer jelentőségét, mondván a soros feldolgozás elavult Ezzel szemben: képfájlok (GIF, JPEG), hangfájlok, nyomtató parancsfájlok, weblapok, irodai alkalmazások saját fájl-formátumaik soros elérésű fájlok Például: Word-el írt fájlt átalakítása Apple Macintoshon futó szövegszerkesztő formátumára. Felmérések mutatják, hogy Európában ma is elterjedten használják a módszert, Amerikában ez az arány kisebb
Az adatfolyam tervezési módszer a megtervezni kívánt program adatáramlási rendszerének és adatkezelési folyamatainak tanulmányozásán alapul. Célja egy program átfogó felépítésének meghatározása. A programot alkotó modulok A modulok logikai kapcsolatrendszere Leginkább közepes vagy kifejezetten nagy rendszerek tervezése során használható
Tervezzünk programot, mely a Celsiusban megadott hőmérsékletet Fahrenheitre számítja át! Első lépés az adatfolyam-diagram (adatáramlás-diagram, Data Flow Diagram, DFD) felrajzolása. Az nyilakat (adatáramokat) és köröket (folyamatokat) tartalmaz. Billentyűzet Hőmérséklet Celsiusban Hőmérséklet Fahrenheitben Bemenet Átalakítás Kimenet Az a program átfogó logikai szerkezetét
Bemenet Párbeszéd a felhasználóval, mely bekéri a bemenő adatot Ellenőrzés, hogy a felhasználó valóban számot adott-e meg A hiba kijavítása, ha megadott bemenet érvénytelen A bemenet átalakítása a megfelelő belső formátummá Feldolgozás Az érték átalakítása a Fahrenheit skálán kifejezett hőmérsékletté úgy, hogy közben a kívánt pontosság megmaradjon Kimenet A kiszámított hőmérséklet megjelenítése a képernyőn a megkívánt formában
Második lépés: az adatáramlási diagramot programszerkezeti diagrammá alakítjuk. Ez a program moduljait, valamint azok kapcsolatrendszerét tartalmazza Az átalakítás lépései: Állapítsuk meg, hogy melyik a legfontosabb folyamat (példánkban az átalakítás) Ez lesz a programszerkezet legmagasabb szintjén elhelyezkedő modul Ezt az egységet gondolatban a levegőbe emeljük, és elképzeljük, hogy lóg le róla a többi szerkezeti elem. Így egy fagráfként ábrázolt hierarchiához jutunk. Alakítsuk a folyamatokat jelölő köröket modulokat ábrázoló téglalapokká, az adatáramoknak megfelelő nyilakat pedig modulhívásoknak megfelelő vonalakká
Átalakítás Bemenet Kimenet Adattár Billentyűzet Név Név és telefonszám Bemenet Lekérdezés Kimenet Képernyő
1. Egyetlen nagy buborékkal kezdjük a rajzolást, amely a program teljes működését leírja, majd ezt kisebb egységekre, részfolyamatokra bonjuk 2. A kimeneti adatáramból indulunk ki, majd a szerkezetben visszafelé haladunk 3. A bemeneti adatfolyam útját követjük a logikai szerkezetben előre haladva A diagram felrajzolására nincs jól meghatározott, szisztematikus eljárás
Vonalkód Érvényesítés Érvényes vonalkód Keresés Ár Ár Formázott ár küldése az 1. terminálra Ár Formázott ár Összeg Az összeg frissítése Formázott ár küldése a 2. terminálra Az összeg formázása Formázott ár Formázott összeg
Keresés Érvényesítés Az összeg frissítése Formázott ár küldése az 1. terminálra Formázott ár küldése a 2. terminálra Összeg formázása
A tervezési módszer a modulok és azok kapcsolatrendszerének azonosításával megadja a megvalósítandó program világos logikai felépítését, de az egyes modulok belsejét külön-külön is meg kell terveznünk. Szükségünk van alacsonyabb szintű tervekre is, melyek készülhetnek Michael Jackson módszerrel, a funkcionális felbontás módszerével vagy bármely más alacsony szintű tervezésre megfelelő módszerrel.
Az adatfolyam tervezési módszer (Larry Constantine) egyidős a moduláris programozással A módszer lényeges elemét képezi egy általában strukturált tervezésnek (Structured Design) nevezett eljáráscsomagnak Jól használható mindazon esetekben, amikor az adatáramlásnak központi jelentősége van a feladat megoldása szempontjából A legtöbb lépés kreativitást, beleérző képességet kíván
Természetes nyelv formális leírás A programok specifikációját, dokumentációját általában természetes nyelven készítik el. Ez tartalmazhat félreérthető elemeket Matematikai eszközök használatán alapuló formális leírás egyértelmű Ha a megbízhatóság, biztonság kiemelt fontosságú
Matematikailag elemezhetők, vagyis matematikai bizonyítási módszereket használhatunk a leírás helyességének vizsgálata során A leírások könnyebben karbantarthatók A formális leíráshoz használt nyelv bővíthető A programok helyességét, a leírással való összhangját matematikai szigorúsággal bizonyíthatjuk Lehetővé teszi a leírás program átalakítás automatizálását
0. szint: formális specifikációt készítenek, majd a fejlesztés hagyományos eszközökkel folyik formal methods lite A legtöbb esetben a legköltséghatékonyabb választás 1. szint: formális fejlesztés és ellenőrzés Nagy integritású rendszerek fejlesztésekor 2. szint: A tervezés egyes lépéseinek helyességét (mint matematikai tételeket) bizonyítják (Automatic Theorem Prover) Nagyon drága, csak akkor éri meg, ha a hibák költsége különlegesen nagy
Leírás (specifikáció) modell alapú megközelítés matematikai fogalmakkal jellemzi a program futása során felvehető egyes állapotokat, állapotátmeneteket (műveleteket) Tervezés Az elvont matematikai modell közelítése egy konkrét programnyelv eszközeihez (adatfinomítás) Megvalósítás Kódolás (műveleti finomítás)
Z formális nyelv (Z notation, ejtsd zed) Vienna Development Method (VDM)
1. Leírás A matematikai modell megalkotása (sémák) Felső rész: az állapottal kapcsolatos összetevők Alsó rész: invariáns, melynek igaznak kell maradnia állapotváltozáskor A könyvtár két halmazból áll: a bent lévő és a kikölcsönzött könyvek halmazából Egy típus bevezetése: KATNO katalógusszám, illetve azok halmaza Konyvtar kolcsonozheto, kikolcsonzott: P KATNO kolcsonozheto kikolcsonzott = { } KATNO hatványhalmaza predikátum, melynek igaznak kell maradnia (invariáns)
Műveletek megadása ellenőrzés: az invariánsoknak igaznak kell maradniuk pl. Kolcsonzes művelet
a művelet előtti és utáni állapotok leírása bemeneti változó Kolcsonzes ΔKonyvtar előfeltétel konyv?: KATNO konyv? kolcsonozheto kolcsonozheto' = kolcsonozheto \ {konyv?} kikolcsonzott' = kikolcsonzott {konyv?} művelet utáni állapot művelet előtti állapot A predikátumok logikai ÉS kapcsolatban állnak. A ΔKonyvtar séma automatikusan a rendelkezésünkre áll ( modularitás) ΔKonyvtar kolcsonozheto, kolcsonozheto': P KATNO kikolcsonzott, kikolcsonzott': P KATNO kolcsonozheto kikolcsonzott = { } kolcsonozheto' kikolcsonzott' = { }
A Kolcsonzes séma teljes alakja sémabeszúrás nélkül a következőképpen nézne ki Kolcsonzes2 kolcsonozheto, kolcsonozheto': P KATNO kikolcsonzott, kikolcsonzott': P KATNO konyv?: KATNO konyv? kolcsonozheto kolcsonozheto kikolcsonzott = { } kolcsonozheto' kikolcsonzott' = { } kolcsonozheto' = kolcsonozheto \ {konyv?} kikolcsonzott' = kikolcsonzott {konyv?}
A Visszavetel művelet leírás az előbbihez ha-sonlóan a következő Visszavetel ΔKonyvtar konyv?: KATNO konyv? kikolcsonzott kikolcsonzott' = kikolcsonzott \ {konyv?} kolcsonozheto' = kolcsonozheto {konyv?}
A leírás helyességének ellenőrzése Az, hogy a teljes logikai rendszert Z nyelven fogalmaztuk meg, még nem biztosítja annak helyességét. Megfelel-e a leírás a megrendelő által megfogalmazott elvárásoknak? Követtünk-e el valamilyen hibát a Z nyelv használata közben? Bizonyítanunk kell a modell helyességét, egyfajta matematikai tételként kell azt kezelnünk. Például vizsgáljuk meg, milyen hatással van egy könyv kikölcsönzése a könyvtár teljes raktárkészletére. Nyilvánvaló, hogy a könyvállománynak nem szabad megváltoznia. Bizonyítsuk be, hogy ennek az elvárásnak megfelel a modellünk
Tehát a bizonyítandó állítás kolcsonozheto' kikolcsonzott' = kolcsonozheto kikolcsonzott Bizonyítás: kolcsonozheto' kikolcsonzott' 1. = (kolcsonozheto \ {konyv?}) (kikolcsonzott {konyv?}) a Kolcsonzes művelet meghatározása alapján 2. = (kolcsonozheto \ {konyv?}) ({konyv?} kikolcsonzott) az unióképzés kommutatív 3. = ((kolcsonozheto \ {konyv?}) {konyv?}) kikolcsonzott az unióképzés asszociatív 4. = (kolcsonozheto {konyv?}) kikolcsonzott az unióképzés és a különbség közötti általános összefüggés 5. = kolcsonozheto kikolcsonzott a Kolcsonzes művelet konyv? kolcsonozheto kitétele miatt
2. Tervezés Elkészítettünk egy logikailag ellenőrzött, halmazokkal megfogalmazott elvont leírásunk Az elvont adattípusokat át kell alakítanunk olyan szerkezetekké, melyek könnyen megfeleltethetők a programozás során használható szerkezeteknek. (Halmazok helyett pl. tömbök) Ezeket a Z nyelv új eszközeivel, a függvényekkel valósítjuk meg
Pl. Kkolcsonozheto: K: konkrét k1 k2 k4 1 2 3 4 5 na = 3 Kkikolcsonzott: nb = 2 k3 k5 1 2 3 4 5 A Z nyelvben a tömb egy függvénnyel modellezhető, példánkban Kkolcsonozheto, Kkikolcsonzott: N 1 KATNO ahol N 1 = {1, 2, 3, } a Z nyelv egy alapvető halmaza és a példánk szerint: Kkolcsonozheto = {1 k1, 2 k2, 3 k4, } na =3 Kkikolcsonzott = {1 k3, 2 k5, } nb =2 A programnyelvekben használatos Kkolcsonozheto[2] hivatkozás megfelel a Z nyelv Kkolcsonozheto(2) függvényhívásának.
Mint a leírásnál, a konkrét modellt is egy séma formájában fogalmazzuk meg: Kkolcsonozheto, Kkikolcsonzott: N 1 KATNO na, nb: N i,j: 1..na i j Kkolcsonozheto(i) Kkolcsonozheto(j) i,j: 1..nb i j Kkikolcsonozott(i) Kkikolcsonzott(j) i: 1..na ( j: 1..nb Kkolcsonozheto(i) Kkikolcsonzott(j))
A KKonyvtar séma invariánsa három univerzális meghatározásból áll, melynek általános alakja: deklarációk predikátum azaz valamennyi így bevezetett változóra teljesülnie kell a következő állításnak A példában az állítások azt jelentik, hogy nem lehet egyik tömbnek sem ismétlődő eleme, illet nem szerepelhet egyszerre egy katalógusszám mindkét tömbben
A konkrét Kolcsonzes művelet: KKolcsonzes ΔKKonyvtar konyv?: KATNO i: 1..na konyv? = Kkolcsonozheto(i) na' = na - 1 Kkolcsonozheto' = squash({i} Kkolcsonozheto) nb' = nb + 1 Kkikolcsonzott' = Kkikolcsonzott (nb' konyv?)
deklaráció predikátum a változónak létezik olyan értéke, amelyre az állítás igaz s f tartománykivonás: azt a függvényt jelenti, amely úgy keletkezik, hogy az f függvény értelmezési tartományából elvesszük az s tartományt. squash: az indexek átrendezésével összehúzza a lyukas tömböt
Még formálisan be kell bizonyítani, hogy a KKolcsonzes művelet valóban a Kolcsonzes művelet finomítása a két séma előfeltétele egyenértékű, azaz valahányszor a Kolcsonzes végrehajtható, mindannyiszor a neki megfelelő KKolcsonzes is elvégezhető; a Kolcsonzes és a konkrét KKolcsonzes művelet által előállított végállapotok egyenértékűek Ezt az egyenértékűséget természetesen a tervben szereplő valamennyi műveletpárra be kell bizonyítanunk Mindez nem egyszerű feladat
3. Megvalósítás A következő lépés az elvont leírás meg-valósítása, vagyis a kódolás intuitív módon megalkotjuk a szükséges algoritmusokat, majd a keletkezett kódot formális módszerek használatával összevetjük az eredeti tervvel; formális átalakítási szabályok alkalmazásával közvetlenül állítjuk elő az elvont tervből a kódot (műveleti finomítás).
Kialakulása a 60-as évek végér tehető Válasz a szoftverkrízisre A szoftverfejlesztés során az együtt változó részek elkülöníthetők Projektek közötti újrahasznosíthatóság növelése
Bezárás - az információ elrejtése: az adatokat csak interfészeken (metódusok) keresztül lehet elérni. Öröklődés - az utód osztály örökli az ős adatait, metódusait, valamint tartalmazhat újakat, és felülírhat régi metódusokat. Polimorfizmus többalakúság: ugyanarra a metódus hívásra, különböző objektumok különbözőképpen reagálhatnak. Utánzás, modellezés elvének alkalmazása a programozásban
Egy objektumorientált program egymással kommunikáló objektumok összessége, melyben minden objektumnak megvan a feladatköre fut vezérlő objektum üzenet3 objektum3 üzenet1 üzenet2 objektum1 objektum2
A szükséges osztályok azonosítása: az adott alkalmazási terület milyen osztályok, objektumok bevezetését teszi szükségessé. A jó tervezés kulcsa a valóság valamely részének közvetlen modellezése, vagyis a program fogalmainak osztályokra való leképezése. Az osztályok feladatainak meghatározása: meg kell határozni a rendszerben előforduló valamennyi osztály szerepét és feladatát. Az osztályokkal együttműködő osztályok meghatározása
Felhasználási esettanulmányok alapján finomítani kell az osztályok feladatköreit (use case): kiválasztunk jellemző alkalmazási példákat, és a terv alapján nyomon követjük az üzenetek objektumok közötti áramlását. A használati esetek a rendszert (dinamikusan) működő egységként tekintik. Át kell tekintenünk az osztályok egymás közötti viszonyát Hierarchiába szervezés: ez az öröklődés révén lehetővé teszi a kód újrahasznosíthatóságát; elvont osztályok Újrahasznosítható tervezési keretrendszerek létrehozása: egymással együttműködő osztályok rendszere valamilyen feladatkör megoldására
Objektumközpontú tervezés szintjei: 1. Architektúrális tervezés - a létrehozandó programot mint egészet érintő kérdésekben döntünk. 2. Külső interfész tervezése - a külvilággal történő kapcsolattartás módját és részleteit írja le. 3. Az objektumtervezés (más néven részletes tervezés) - a programot felépítő elemek objektum orientált megközelítésben az osztályok és objektumok egyenkénti specifikálása oly módon, hogy azok akkor is együtt tudjanak működni, ha a különböző elemeket, különböző programozók implementálják.
Fő feladata: ügyfél elégedettsége a használt szoftverrel kapcsolatosan Az elégedettség természetes, nem vesszük észre Az elégedetlenség azonnal tudatosan jelentkezik
Szoftver meghibásodása, nem megfelelő működése Okai lehetnek: Hardveres hiba Hálózati hiba Konfigurációs hiba Kezelői hiba Nem megfelelő környezet Adatsérülés
Programhiba Emberi tévedés Ismerethiány Segédprogramok hibái Rohammunka Szervezési hiba
Szűk határidők Fáradtság Túlterheltség Zavaró környezeti körülmények (zaj, hőmérséklet, stb.) Gyakorlatlanság Túl bonyolult feladat Ellentmondásos célok
A fellépő hibák csökkentése Megbízhatóság növelése Szabványoknak való megfelelés Ügyfél elégedettség növelése a cél
Quality Az IEEE szerint a minőség: az a szint, amikor a komponens, a rendszer vagy folyamat megfelel a meghatározott követelményeknek és/vagy a felhasználó/ügyfél igényeinek, elvárásainak. Befolyásoló szoftverjellemzők Funkcionális funkcionalitás Nem funkcionális megbízhatóság, használhatóság, hatékonyság, karbantarthatóság, hordozhatóság
Szabványok, szabályzatok Képzés Tesztelés Hibaelemzés
Milyen mértékben kell tesztelni? Fő feladat az optimális érték megtalálása Túl kevés teszt sok hibát hagy benne Túl sok tesz már nem éri meg Kockázat (Risk) A jövőbeni negatív következményekkel járó esemény
Tesztelés (testing) Az összes fejlesztési életciklushoz kapcsolódó akár statikus, akár dinamikus folyamat, amely a szoftvertermékek tervezése, elkészítése, kiértékelése során megállapítja, hogy a szoftver teljesíti-e a meghatározott követelményeket, megfelel-e a célnak. Minden esetben a tesztelés felelős a hibák megtalálásért.
Hibakeresés (Debugging) A szoftver meghibásodás okainak megtalálási, analizálási és eltávolítási folyamata A hibakeresés nem tesztelés!!! A hibakeresés fejlesztői tevékenység!
Teszttervezés és irányítás Meg kel határozni a célokat a tevékenységeket a határidőket Aktuális folyamat összehasonlítása a tervvel Eltérések kiértékelése Szükséges módosítások elvégzése
A tesztbázis áttekintése Értékelés tesztelhetőség szempontjából A tesztfeltételek és azok prioritásának meghatározása A tesztesetek megtervezése és prioritásuk meghatározása A tesztadatok meghatározása A tesztkörnyezet megtervezése Nyomonkövethetőség kialakítása
A tesztesetek fejlesztése azok prioritásának meghatározása A teszteljárások fejlesztése és prioritásuk beállítása Tesztkészletek létrehozása Tesztkörnyezet ellenőrzése A prioritásnak megfelelően a tesztek végrehajtása Dokumentálás Az elvárt és a kapott eredmények összehasonlítása Eltérések jelentése
A tesztterv kilépési feltételeinek összehasonlítása a tesztnaplókkal Ezek alapján eldöntendő, hogy további tesztelés szükséges-e? Tesztösszefoglaló jelentés elkészítése
A meghatározott átadandó elemek ellenőrzése A problémák (issue) jelentések lezárása A rendszer átvételéről szóló dokumentum elkészítése A tezst infrastruktúra és a hozzá tartozó testware véglegesítése és archiválása A testware átadása a karbantartást végzőknek Tapasztalatok feldolgozása Információk hasznosítása a tesztfolyamat érettségének fejlesztéséhez
Független tesztelő Nem ellenérdekelt Tesztelési technikák ismerete Más látásmód, más szemlélet Sok esetben költséghatékonyabb A szoftver fejlesztője Ismeri a technológiát Ismeri a kódot Ismeri a követelményeket És amúgy is teszteli saját munkáját
Fejlesztő tesztel A fejlesztő csapaton belül van tesztelő A tesztelő csapat független, de közös a vezetés A felhasználóktól független tesztelők Szakosodott tesztelői szakértő Külső cég által tesztelve
Mi kell a hibák feltárásához? Kíváncsiság Célorientáltság Szakszerű pesszimizmus Kritikus szemlélet A részletekre való aprólékos odafigyelés Jó kommunikációs készség Hatodik érzék tapasztalat a hibasejtéshez
Alapértelmezett tulajdonságok Olvasási készség!!!!! Jelentések elkészítésében való jártasság Megfelelő szintű tapasztalat Alkalmazási és üzleti területen Technológiában Tesztelésben
Fontos a problémák tárgyilagos tálalása Vegyük figyelembe a másik fél álláspontját, próbáljuk megérteni Mindig ellenőrizzük, hogy sikerült-e egymást megérteni A jót és a rosszat is jelezzük vissza, legyen teljes a kommunikációnk
A tesztelés hibák jelenlétét jelzi: A tesztelés képes felfedni a hibákat, de azt nem, hogy nincs hiba. Növeli a szoftver minőségét és megbízhatóságát. Nem lehetséges kimerítő teszt: Minden bemeneti kombinációt nem lehet letesztelni és nem is érdemes. Csak a magas kockázatú és magas prioritású részeket teszteljük. Korai teszt: Érdemes a tesztelést az életciklus minél korábbi szakaszában elkezdeni, mert minél hamar találunk meg egy hibát, annál olcsóbb javítani. Ez azt is jelenti, hogy nemcsak programot, hanem dokumentumokat is lehet tesztelni. Hibák csoportosulása: A tesztelésre csak véges időnk van, ezért a tesztelést azokra a modulokra kell koncentrálni, ahol a hibák a legvalószínűbbek, illetve azokra a bemenetekre kell tesztelnünk, amelyre valószínűleg hibás a szoftver.
A féregirtó paradoxon: Ha az újratesztelés során mindig ugyanazokat a teszteseteket futtatjuk, akkor egy idő után ezek már nem találnak több hibát. Ezért a tesztjeinket néha bővíteni kell. A tesztelés függ a körülményektől: Másképp tesztelünk egy atomerőműnek szánt programot és egy beadandót. Másképp tesztelünk, ha a tesztre 10 napunk vagy csak egy éjszakánk van. A hibátlan rendszer téveszméje: Hiába javítjuk ki a hibákat a szoftverben, azzal nem lesz elégedett a megrendelő, ha nem felel meg az igényeinek. Azaz használhatatlan szoftvert nem érdemes tesztelni.
Feketedobozos (black-box) vagy specifikáció alapú A specifikáció alapján készülnek a tesztesetek, a tesztelő nem látja a forráskódot. Van egy lefordított szoftverünk, és egy adott bemenetre tudjuk, milyen kimenetet kellene adni a programnak Fehérdobozos (white-box) vagy strukturális teszt a forráskód alapján készülnek a tesztesetek. Struktúra lefedettsége a struktúra hány százalékát tudjuk tesztelni a meglévő tesztesetekkel. Tesztelhetők a kódsorok, elágazások, metódusok, osztályok, funkciók, modulok.
Fejlesztői tesztek Komponensteszt A rendszer egy komponensét teszteli Integrációs teszt Kettő vagy több komponens együttműködési tesztje Rendszerteszt Az egész rendszert, azaz minden komponenst együtt tesztel Átvételi teszt A felhasználók a kész rendszert tesztelik
A rendszer önálló részeit teszteli általában a forráskód ismeretében Legismertebb fajtái unit-teszt metódusokat teszteli Vizsgálja, hogy a tényleges visszatérési érték megegyezik-e az elvárttal. A unit-tesztnek nem lehet mellékhatása! Modulteszt - a modul nem-funkcionális tulajdonságát teszteli
A komponensek közti interfészeket, az operációs rendszer és a rendszer közti interfészt, illetve más rendszerek felé nyújtott interfészeket tesztelik Az összeillesztés során keletkező hibákat keresi Típusai: Komponens komponens integrációs teszt: A komponensek közötti kölcsönhatások tesztje a komponensteszt után. Rendszer rendszer integrációs teszt: A rendszer és más rendszerek közötti kölcsönhatásokat tesztje a rendszerteszt után.
A kész terméket teszteli, hogy megfelel-e a követelményeknek Követelmények: a követelmény specifikáció a funkcionális specifikáció a rendszerterv Gyakran független cég végzi
Az egész rendszert teszteli A tesztelést a végfelhasználók végzik Típusai: alfa teszt - teszt a fejlesztő cégnél béta teszt végfelhasználók szűk csoportja tesztel felhasználói átvételi teszt szélesebb béta teszt, majdnem minden felhasználóval üzemeltetői átvételi teszt - rendszergazdák ellenőrzik, hogy a biztonsági funkciók, pl. a biztonsági mentés és a helyreállítás, helyesen működnek-e