ugrás a tartalomhoz

Program tervezés a gyakorlatban

s_volenszki · 2009. Nov. 8. (V), 15.47
Amióta ismerem a Weblabort és természetesen titeket, kedves WL Tagok, nagyon sokat tanultam, sok minden tisztább azóta. Nem lenne egy utolsó szempont ugyan ezzel a tudással 18 évesen újrakezdeni a főiskolát... ;)

Az elmúlt fél évben jelentős fejlődést tudhatok magam mögött:

- Megbizonyosodtam, hogy a logikai képességeimhez legmegfelelőbb programtervezési minta a funkcionális felbontás.

- Megértettem az MVC-ben rejlő erőt, hogy hogyan vagyok képes egy strukturális felépítés segítségével több tízezer sornyi forráskódot átláthatóan kezelni és karbantartani.

- Megértettem a moduláris alkalmazás tervezés fontosságát, jelentőségét.

Van azonban egy két terület, amit továbbra is csak részben képes átvilágítani az értelem és tudás napjának sugara, és amíg ez így lesz, úgy érzem nem tudok tovább lépni. Mivel alapvetően az alkalmazás tervezés és kivitelezés egy fajta tudásvágyam, kedvenc időtöltésem, úgy érzem tovább kell feszegetnem képességeim határát.

A köd:

Két fő témakör van, amiben keresem a megértést:

1. Moduláris programtervezés (Programtervezés)
2. Viselkedési minták, a megfigyelő (Programtervezési minták)

1. A Moduláris programtervezéssel alapvetően egyet értek és alapjaiban értem is, azonban vannak kérdéseim.

Hogyan határozzuk meg, mi legyen egy modul és az mekkora legyen?

A témában olvasott könyvek bemutatnak néhány hasznos fogást arra, hogyan tervezzünk modulokat, és hogyan vizsgáljuk azok bonyolultságát, azonban felmerült bennem egy kérdés. Mit is nevezünk pontosan modulnak? A modul szót, az előfordulásának körülményeitől értelmezhetjük egy alkalmazás rendszer egy egységének, mint például Drupal-ban egy blog, vagy egy naptár, azonban a tervezési minták szerint a modul egy olyan egység, amelynek egy, vagy néhány jól meghatározott feladata van, az ajánlás szerint ne legyen hosszabb 40-50 sornál. Van akik azt ajánlják, hogy egy modul, ne rendelkezzen 5-9-nél több feladattal, mert az átlagos emberi agy nagyjából 7 logikai összefüggést képes egyszerre értelmezni. Sok érv hangzik el kisméretű modulok mellett, ellen, a végeredmény mégis az, hogy kisméretű, jól áttekinthető modulokból érdemes építkezni.

De mégis! Hogyan lehet ezek alapján eldönteni, mi legyen egy modul? A szakirodalom említ egy eljárást, amivel megmérhetem, mennyire bonyolult egy modulom. Az McCabe eljárás szerint, meg kell számolni, hány döntési szerkezet található egy modulban. Apropó! MVC-ben egy modulba tartozik minden model, controller és esetenként view template és javascript-je? Ezekben mindben lehet döntési szerkezet.

Egy egyszerű példa:

Egy ügyfelek nyilvántartására szolgáló, MVC strukturált program, ami egy nagyobb rendszer része (mondhatnám modul, de szándékosan nem teszem), csak az új ügyfél hozzáadása funkcióban tartalmazhat akár (az általam készítettet számoltam meg) 30 döntési szerkezetet is (Controller:9, model:7, view:4, js:10).

Ez azt jelenti, hogy ezt a funkcionális egységet fel kellene bontani modulokra? Mondjuk úgy, hogy egy külön modulra bízom a bevitt adatok érvényességének ellenőrzését, egy másikra a hibakezelést UI-n, egy harmadikra pedig az adatok bevitelét? És ha ez így egy jó elképzelés, akkor hogyan kell ezt MVC-ban kezelni? Ha jól emlékszem MVC-ben a controller az, ami döntési szerkezeteket tartalmazhat.

Alapvetően van egy controller, ami az MVC felépítésből adódik, majd ez a controller includol-ja a modulok controllereit? Na ez itt a köd egyik fele.

2. Viselkedési minták, a megfigyelő

Nagyon tetszik az elmélet, azonban nem tudom gyakorlatba ültetni. A könyv azt írja, hogy a moduláris felépítés akkor jó, ha a modulok között gyenge a csatolás és magas a kohézió, azaz minden egyes modul csak egy ponton csatlakozik bármelyik másikkal.

Ez az elv alapvetően megköveteli, hogy minden egyes modul úgy önmagában legyen a lehető legteljesebb és semmi mással ne foglalkozzon. Ha elvégezte a feladatát, egy meghatározott ponton biztosítsa a feladat ellátása során keletkező adatokat más, olyan moduloknak, amelyek azzal dolgozni akarnak.

A megfigyelő viselkedési minta erre tökéletesen jó lehet, hiszen pont az a lényege, hogy minden egyes egység tudja a saját dolgát, mikor elkészül elkészül az a bizonyos saját dolog, akkor kikiáltja, hogy készen vagyok, majd a megfigyelő értesíti az összes olyan egységet, akik előre jelezték, hogy szükségük van azokra az adatokra.

Példa:

Mikor új tételt akarunk rögzíteni egy számlázó programban, akkor partnert kell választanunk (pl.: legördülő listából). Ezekben az esetekben viszonylag gyakorta előfordul, hogy a partner nem létezik. Ebben az esetben egy gombnyomással meghívható az az egység, ami az új partner rögzítésével foglalkozik. Elvégzi a feladatát, majd kiált egyet, hogy készen vagyok. Ezek után a megfigyelő szól egy erre az eseményre feliratkozott másik egységnek, akinek az a feladata, hogy újratöltse a partnerek legördülő listáját. Helyes ez így? Jól gondolom, hogy szerver-kliens modellben a megfigyelő többnyire kliens oldali (pl.: js), és az esemény feliratkozásokat is kliensen kell végrehajtani?

Miből áll egy eseményre feliratkozás?

- Én figyelem
- ezeket az eseményeket, és ha bekövetkezik
- ezt, meg ezt, meg ezt fogom tenni?

Röviden ennyi. Kérlek írjátok meg a véleményeteket. Csak én vagyok ennyire nehéz fejű, vagy tényleg nem vagyok képes megérteni valamit! Köszönöm!

s_volenszki
 
1

Modul

janoszen · 2009. Nov. 8. (V), 16.35
Modul az, amit annak definiálsz. Erre nincs konkrét meghatározás. Én pl úgy definiáltam a modelt, hogy egyrészt lehetnek neki függőségei, másrészt nem tartalmazhat projekt-specifikus részeket. Tehát ha valamit úgy érzek, hogy azt két helyen is szeretném használni, kiteszem külső modulba, aztán akinek kell, majd jól berángatja.

A második kérdésedre inkább egy ellenpéldát mondok. Vannak olyan rendszerek, amik minden egyes eseményt átadnak a szerver oldalnak, hogy az jól megfigyelhesse. Na ilyet nem szeretnél. Mivel a web nagyon nagy százalékban felülettervezés, nem érdemes magad sarokba szorítani egy lehetőséggel, kicsit flexibilisnek kell lenni és a követelményeket követni. Ha a formjaid önálló egységként egyszerűen példányosíthatóak, már nem egy ördöngősség összerakni ezek egymás utániságát vagy akár AJAXos betöltését.
2

További gondolatok

s_volenszki · 2009. Nov. 8. (V), 19.16
Modul:

Ez tehát azt is jelenti, hogy a modul valójában nem más, mint egy olyan egyértelmű és jól értelmezhető egység, ami egy, vagy néhány feladat elvégzésére hivatott. Az, hogy az a néhány feladat mennyi is valójában, az a struktúra és a fejlesztő képességein is nagy mértékben múlik.

Ha például egy komplex rendszer része egy számológép, akkor az a teljes komplex rendszer szempontjából egy beépülő egység (nevezhetjük akár modulnak), azonban a számológép, mint program egység is állhat önálló, egy vagy néhány feladatot elvégző egységekből, például:

- bevitt adat formai ellenőrzése
- összeadás modul
- kivonás modul
- szorzás modul
- osztás modul

Azonban a számológép programban található funkció, ami a bevitt számot ellenőrzi formailag, annak ugye elég nagy az esélye, hogy más önálló egységben is szükség lehet rá, így az nem privát modulja lesz a számológép programnak, hanem a főmodul olyan funkciója, ami elérhető minden további modul számára.

Ez rendben van, elfogadható, racionális. Hogyan befolyásolja ez (befolyásolja egyáltalán) a MVC struktúrát? Én jelenleg így csináltam meg a struktúrát:

/library (ide jön minden olyan, amit minden modul használhat /smary,swift,fpdf,zip/)
/modules
    /ezegymodul
        /controllers (C)
        /helpers (a nézetek segítségei /meta,doctype,css,js/
        /locale (nyelvek)
        /models (M)
        /views (V /smary tpl/)
    /...
/public_html
    /static
        /ezegymodul
            /css
            /images
            /js
        /...
    /library (jQuery,tinyMCE)
    .htaccess
    index.php


Úgy látom, hogy ez megfelel az alapvető elvárásoknak, még azon kell elgondolkoznom, hogy a /library könyvtárban legyen egy olyan könyvtár, amibe bekerülnek a főmodul funkciói, és minden egyes funkció önálló fájl legyen, mint a smarty plugins vagy modifier-ek. Ezeket a fornt kontroller include-olja (ami valójában a "főmodul"), ezért aztán minden további gyermek modul számára elérhetőek.

Igen, most is többször belekeveredek ebbe az elnevezés kérdésbe és baromira zavaró, hogy egy alkalmazás rendszerben modulnak hívjuk a funkcionális egységeket (számlázás, készletgazdálkodás, partner nyilvántartás, számológép), pedig mélységében éppen arról van szó, hogy az ügyfél rögzítése során, a bankszámlaszám formai megfelelőségét ellenőrző egy-két funkció egy modul (ami éppen publikus modul, nem is privát). Tanulságos...

Viselkedés minta:

Ez nagy igazság:
Mivel a web nagyon nagy százalékban felülettervezés, nem érdemes magad sarokba szorítani egy lehetőséggel, kicsit flexibilisnek kell lenni és a követelményeket követni.


Az alapvető követelmény az, hogy rugalmas legyen egy rendszer. Ha megvan tervezve és le van kódolva egy olyan alkalmazás (néhány modulból) ami képes új ügyfelet rögzíteni, akkor logikus elvárás, hogy egy új megrendelés rögzítése közben, ha a vevő még nincs benn az ügyfelek listájában, egy gombnyomásra elindítható legyen az ügyfél rögzítését elvégző alkalmazás.

Mivel többnyire webes alkalmazásokról van szó (nincs SEO), ahol csak lehet én is AJAX-szal kommunikáltatok, így alapvetően minden körülmény adott. Ami az újdonság erejével hat, az az, hogy egy-egy alkalmazás már inicializáláskor kell, hogy ismerje az összes eseményre feliratkozó objektumot, azok lehetséges eseményeit és az eseményekre bekövetkező funkciókat (naivság is lenne ezt másképp feltételezni, hiszen az sok mindenről árulkodna, de nem a pontos és részletes tervezésről).

Tehát a feladat adott, azt hiszem a köd oszlik és már látom azokat a messzi-messzi pontokat, ahova el akarok jutni!
3

Kék könyv

erenon · 2009. Nov. 8. (V), 19.32
Sajnálom, hogy nincs időm többet írni, így csak két könyvet említenék, aminek sokat köszönhetek:
McConnell: Code Complete 2
GoF: Design Patterns

Utóbbit említetted, de javaslom, hogy az angol kiadást olvasd.
4

Hmm

s_volenszki · 2009. Nov. 9. (H), 19.18
Ez a Code Complete 2 érdekesnek mutatkozik!

Köszönöm!