Tuesday, April 8, 2008

Arhitektura na tri nivoa

Tronivovska arhitektura je poznatija kao "3-tier architecture" (od n-tier) koju je Microsoft prisvojio za web aplikacije koje barataju podacima ciji je izvor i odrediste baza podataka (dakle klijent-server arhitektura), a inace je ideja ziva vec poodavno. Medjutim, Microsot je prvi omogucio da u svom IDE alatu (Visual Studio) vizuleno povezete nivoe koji su do tada bili samo teoretski povezani, a programer je morao da zna sta i odakle poziva.

N-Tier arhitektura ima daleko vise nivoa, ali je arhitektura obicne desktop i web aplikacije svedena na osnovna tri - podaci (data access), logika (bussines logic) i prezentacija (presentation). Koncept se zasniva na tome da svaki nivo radi svoj posao, da je svaki nivo "ucauren" (ko zna sta on radi, prim aut.) i da svaki od njih moze biti koriscen sa vise strana (npr. istu logiku i pristup podacima mogu da koriste web i windows aplikacija) sto omogucava modularnost. Takodje, pri izvrsavanju programa nivoi se ne mogu preskakati (sem u izuzetnim slucajevima) vec proces ide korak po korak (jel to neko pomenuo Windows Workflow Foundation?)

Podaci - U ovom nivou se samo odredjuje pristup podacima i definisu CRUD operacije (CReate, Update i Delete), bilo one store procedure ili zivi upiti. Konekcija na bazu se takodje vrsi iz ovog nivoa. Dakle, bilo sta sto se radi sa bazom podataka se nalazi u ovom sloju.

Poslovna logika - Ovaj sloj definise sta se radi sa podacima koji dolaze/odlaze iz aplikacije/baze podataka. Ispituju se pravila upisa, konvertuju se podaci i jednog tipa u drugi i tome sl. Ovde bi trebala da se nalazi sva pamet aplikacije.

Prezentacija - Ovo je zapravo samo korisnicki interfejs. Znaci prozori i web stranice. Mnogi neiskusni programeri sve strpaju u ovaj nivo tako da se dobijaju "spageti" u kodu i gomila metoda kojima jednostavno tu nije mesto, vec u poslovnom sloju aplikacije.


Kako bi ovo bilo jasnije, postavicu najjednostavniji primer u formi za kreiranje novog korisnika.

- Prezentacija (ono sto korisnik vidi) sadrzi web/winform kontrole, textbox-ove za unos podataka, labele za opise i dugmad (ili samo dugme). Pored ovoga moraju postojati i EventHandler-i, najmanje jedan, za kontrolu dugmeta "Unesi korisnika". Pritiskom na ovo dugme , poziva se metoda iz biznis sloja kojoj se prosledjuju podaci (ime korisnika, lozinka i e-mail adresa) koji su ucitani iz kontrola.
- Poslovna logika je tu da proveri validnost unetih podataka (format e-mail adrese, proveru domena, provera politike za format lozinke i za naziv korisnika) i da doda jos informacija (datum kada je korisnik kreiran, IP adresa, naziv i verzija browser-a i sl.) i neke default vrednosti (broj logovanja, datum poslednjeg logovanja i sl). U ovom sloju se kreira entitet (tj. objekat iz sloja baze podataka) Korisnik koji predstavlja jedan zapis u tabeli Korisnici. Kada se kreira entitet sa svim ispravnim podacima poziva se jedna od CRUD metoda iz najnizeg sloja kome se prosledjuje ceo entitet popunjen podacima.
- Podaci ili sloj baze podataka prihvata objekat (entitet) sa svojim podacima i izvrsava jednu od operacija koja je pozvana - kreiranje, brisanje ili izmena zapisa. Opcionalno moze vracati rezultate izvrsenja opereracije.


Vise o n-tier arhitekturi mozete pronaci na linkovima:
http://en.wikipedia.org/wiki/Three-tier_(computing)
http://www.microsoft.com/belux/nl/msdn/community/columns/hyatt/ntier1.mspx
3-tier Architecture with ASP.NET 2.0

Regionalizacija

Ako se zeli regionalizovati ceo sajt potrebno je uneti u web.config sledecu liniju u okviru taga:


...

...

U ovom slucaju se ignorisu klijentova regionalna podesavanja (enableClientBasedCulture). Atribut culture se koristi za formatiranje datuma, vremena, brojeva, monete i sl. dok se atribut uiCulture koristi za podesavanje korisnickog interfejsa na odredjeni region/kulturu.

Ako se radi u windows aplikaciji, tu je situacija nesto drugacija. Jedno od resenja je da se doda u app.config promenljiva na nivou aplikacije koja ce da ima vrednost kod kulture koji ce se koristiti.


...



...


U kodu za ucitavanje aplikacije se dodaje:

string sCulture = ConfigurationSettings.AppSettings["uiCulture"];
CultureInfo.CreateSpecificCulture(sCulture);


U oba slucaja je podesen region Srbija sa latinicnim pismom.

Monday, April 7, 2008

GridView dugme u koloni i dodavanje JavaScript-a

Ako ste postavili kolonu koja ima polje tipa dugme (ButtonField) prostoji mala "kvaka" kako uzeti tekst iz nje?

Radi se o tome sto je u ovom slucaju tekst koji se prikazivao u polju zapravo ID zapisa u tabeli. Resenje je dodati u GridView EventHandler na RowCommand, uhvatiti id reda iz GridView-a, zatim prvu celiju (kolonu) i uzeti LinkButton kao prvu kontrolu u celiji i iz njega izvuci tekst.

private void GridView1_OnRowCommand(object sender, EventArgs e)
{
LinkButton btn = (LinkButton) GridView1.Row[Convert.ToInt32(e.CommandArgument)].Cells[0].Controls[0];
Obrisi(btn.Text);
}

Posto ova kolona sadrzi opciju za brisanje, morao sam da dodam i pitanje tipa "Da li zelite brisanje?". Definitivno treba izbeci bilo kakav PostBack makar se radilo i u ASP.Ajax-u. Dakle, treba dodati nekako JavaScript confirm prozor.
Za ovo resenje postoje dve opcije. Jedno je da se dodaje atribut u kontrolu LinkButton pri kreiranju svakog reda ili da se isto ovo dodaje, ali nakon DataBind() metode GridView-a.
Ja sam se odlucio za ovu drugu jer je laksa za implementaciju i ne dodajem nikakav novi event za GridView (neznatno se usporava "punjenje" tabele podacima).
Dakle, kod ide ovako:
...
// punjenje podacima
GridView1.DataSource = podaci.Citaj();
GridView1.DataBind();
DodajAtribut();
...

private void DodajAtribut()
{
foreach(GridViewRow red in GridView1.Rows)
{
LinkButton btn = red[0].Controls[0];
btn.Attribute.Add("onclick", "return confirm('Da li ste sigurni za brisanje?')");
}
}

Kao u prethodnom primeru, uzima se prva kontrola celije i kastuje se u LinkButton. Zatim se na njega dodaje JavaScript u svakom redu tabele sa confirm prozorom (OK i Cancel dugmad) za brisanje.

Dobra praksa (1)

Ovo je samo deo dobre prakse koju cu kasnije dopunjavati. Vazi za manje-vise sve programske jezike, iako su primeri napisani u C#-u.

Petlje
U pocetku beze samo For...Next, Do..Until i While...Whend. Ove dve poslednje se malo koriste (uglavnom za citanje slogova iz DB set-a, npr. ResultSet-a, RecordSeta...) , ali je usla u "modu" petlja foreach (negde je odvojeno, for each).

U slucaju .NET-a petlja foreach se upotrebljava kada ne vrsimo direktne izmene nad podacima koji se nalaze u kolekciji kroz koju "trcimo", kao npr:

foreach (string korisnik in korisnici)
{
Console.Write(korisnik);
}

U slucaju for petlje, sa podacima se moze manipulisati. Ako se radi brisanje zapisa iz kolekcije koja se cita, praksa je da se nakon brisanja izlazi iz petlje, ili vratiti brojac za jednu vrednost manje.

for(int i = 0; i <>
{
korisnici.RemoveAt(i);
--i;
}


U ovom slucaju je broj elemenata je promenljiv, dok je u sledecem fiksan te je bolje dodati novu varijablu kako se ne bi u svakom ciklusu izracunavala duzina niza tj. broj elemenata u kolekciji.

int limit = korisnici.Length;
for(int i = 0; i <>
{
Console.Write(korisnici[i]);
}

Iako neki programeri imaju naviku da im petlja ide od nazad (brojac se dekrementuje), ovaj pristup odstupa od "prirodnog nacina kretanja", tako da ga ne preporucujem.


EventHandler-i
Metode koje "hvataju" dogadjaje su osnova za interakciju korisnika i aplikacije. Mnogi pocetnici programeri grese, pa u ovim metodama "guraju" citavu logiku i obradu podataka, sto je losa praksa. Treba izdvojiti sve sto nema veze sa dogadjajem i sa njegovim argumentima u posebnu metodu i eventaulno joj proslediti neke parametre iz event-a. Dakle, nesto kao:

private void Btn1_OnClick(object sender, EventArgs e)
{
Radi()
}

Ako od nekog podatka koji je vezan za nosioca dogadjaja zavisi izvrsavanje programa, vrsi se ispitivanje i zatim zove odgovarajuci metod:

private void Btn1_OnClick(object sender, EventArgs e)
{
LinkButton dugme = (LinkButton) sender;

if(dugme.Text == "Cuvaj")
Sacuvaj();
else
Osvezi();
}


Uslovi
Za blokove ili "programski tok" se najcesce povezuju if uslovi. Ono sto je bitno je da se kod if naredbe prvo ispituje poslednji uslov (ako ih ima vise) te ako je "veznik" uslova AND tj && tok programa se nastavlja dalje jer uslov nije zadovoljen.

Takodje, treba obratiti paznju na ispitivanje jednakosti. Naime, brze se izvrsava ispitivanje razlicitosti nego jednakosti, tako da ako nema neke preterane potrebe za jednakoscu (kao u prethodnom primeru) bolje je uzeti u obzir razlicitost.