![]() | |
OOP Kuralları Çerçevesinde Nesneler ile Çalışmak | 09.09.2008 01:40:00 |
| Kategori : Visual C# .NET Özet : Makalemiz boyunca oop prensiplerine sadık kalarak bir ürün uygulaması geliştiriceğiz . Uygulamamız içerisinde kullanıcağımız alanlarımızı kendi tarafımızda nesne olarak tasarlayıp o sekilde kullanıcağız . Uygulamanın ilerleyen aşamalarında Binary olarak serileştirme ve okuma işlemlerinede Sql içerisinde Group By deyimlerine ve bir çok önemli noktalara kısaca bakıcağız. | |
Nesneler ile çalışmak . (OOP Kuralları Çerçevesinde ) Yapacağımız uygulamamızda AdventureWorks database i içerisindeki
Production.ProductSubCategory ve Production.Product tablolarını kullanarak
ürünlerimizin kategorilerini ve bu kategoriler içerisindeki ürün miktarlarını
Kategori listbox ımız içerisinde listeleyeceğiz ve kategoriler içerisindeki
bir kategori adına tıkladığımız zaman ürünler kısmında o kategoriye ait ürünlerimizi
listeleyeceğiz . Evet seçeneğini seçer isek ürünlerimiz o anki sepetimize dahil olacak ve alış veriş yapmaya devam edeceğiz. Yukarıda uygulama içerisindeki iş akışını anlattıktan sonra şimdi kodlarımızı yazarak neyi nasıl ve nerde niçin kullandığımızı detaylı olarak inceleyelim ve üzerinde konusalım . İlk olarak ürün kategorilerimizi ve o kategoriye ait kaç adet ürünümüzün bulunduğunu Kategori listemize almak için gerekli olacak metodumuzu Dal.cs adını verdiğimiz class ımız içerisine yazalım . Dal.cs : Dal.cs class ımız bizim database ile ilgili olan işlemlerimizin yürütüldüğü kısım olacaktır. Uygulamamız boyunca dal .cs adını verdiğimiz bu class ımız sayesinde sadece database olaylarını burada işlemiş olacağız . Şimdi database imize ( AdventureWorks) bağlanıp bilgilerimiz
olan Kategori ve Urunlerimizi çekelim. Şimdi kodlarımızı açıklayalım ve kategori ve ürün bilgilerimizi nasıl aldığımızı inceleyelim . İlk önce Sqlconnection ve SqlCommand adında iki adet pointerımızı namespace düzeyinde oluşturduk dal class ımız her örneklendiği zaman database bağlantı string imi zinde oluşmasını sağlamak için dal class ımızın yapıcı metoduna Con = new Sqlconnection (“data source = .; initial catalog = AdventureWorks; integrated security = true; MultipleActiveResultSets = true;”); Şeklinde burada con nesnemizi örnekledik. Bağlantı satırımızda database e ulaşır iken yani bağlantımızı açar iken MARS desteğin inde açık olarak kullanacağımızı belirttik . Mars destegi default olarak açık bir şekilde gelmemektedir. Eğer bir uygulama içerisinde eş zamanlı olarak birden fazla SqlDataReader tanımı kullanacak isek bizim Mars desteğine ihtiyacımız vardır. Mars desteğimizi aktif olarak kullanmak için MultipleActiveResultSets = true; şeklinde açmamız yeterli olacaktır. Simdi dal class ımız içerisinde kategorilerimizi ve ürünlerimizi bir üst katmana yani yonetim katmanımıza ulaştıralım . AnaKategoriGetir metodumuz metot imzasında parametre almaz ve geriye SqlDatareader nesnesi dondurur . Metodumuzun içerisinde SqlCommand hazırlanış aşamasında sql
bağlanıp iki tablo arasında Group by ile gruplama yapıyoruz . select p.ProductSubCategoryId,pps.Name,count(p.Name) from
Production.ProductSubCategory pps join Production.Product p Production.ProductSubCategory ( pps ) tablomuz ile Production.Product tablolarının icindeki ProductSubCategoryId field ları eşit olan verilerimizi adına ve categoryid sine göre gruplandırıp sorgumuzu hazırladık . ProductionProductSubCategory artık pps diyelim. Ve Productin.Product p diyelim . tablolarımızın icerisinde ise p.ProductSubCategoryID , pps.Name , count(p.Name) olarak alanlarımızı çektik . Hangi kategori deki urunden kaç adet oldugunu bize gosteren kısım elbetteki count(p.name) olan kısımdır . Sqlcommand imizi bu sekilde hazırladık dan sonra ConnectionIslemleri adını verdigimiz metotumuz icerisinden baglantımızı actık bu hazırlamıs oldugumuz metotumuz eger baglantı kapalı ise acar acık ise baglantımızı kapatır . Çok işe yarıyan bu metotumuz sayesinde biz dal.cs içerisindeki bu metotu public olarak erisim belirleyicisini acar isek baska class lar uzerinde iken bile baglantımızı açabilir veya kapatabiliriz. Baglantımızı actıkdan sonra return anahtar soz dizimi ile cmd.ExecuteReader() metotu sayesinde bir ust katmana SqlDataReader olarak verimizi ilettik . Simdi aynı işlemin benzerini UrunGetir Metotumuz icin yapalım . UrunGetir metotumuzun metot imzasında int tipinden bir parametre ve geridonus deger SqlDataReader seklindedir . Command ımızı inceleyelim . sqlcommand kısmında yukarıdan parametre olarak gelen ( yani kategori id olarak gelen ) urunleri bulmak isteyecegiz. select ProductId,Name,Color,convert(decimal,ListPrice),SafetyStockLevel from Production.Product where ProductSubCategoryId=@Id Bunun icin yukarıda belirttiğimiz sql komutumuz da Production.Product tablosunda bulunan ProductId,Name,Color,Listprice,SafetyStoctLevel alanlarımızı Production.Product tablomuzda ProductionSubCategory alanına dısarıdan gelen degerimizi olan id nin esit oldugu kayıtları bulup getiriyoruz . Gelen degerimizi bir ust katmana yani yonetim katmanına kategori metotumuzdaki gibi sql data reader seklinde geri veriyoruz . Dal .cs class ımız içerisinde database ile olan tum işlemlerimizi bitirdik . Artık database kısmı ile bir işlemimiz olursa dal.cs icine yazıcagız ve buradan erisim saglayıp bir ust katmana gondericegiz . Gonderdigimiz bu verileri simdi Yonetim katmanı olarak ele aldıgımız Helper.cs adını verdigimiz sınıf icerisinde erisip bilgilerimizi işleyelim . Helper sınıfımız Dal.cs sınıfından gelen verileri işleyip son katman olan form katmanına ulaştıran kısımdır . Helper aynı zamanda bizim ufak işlerimizide yapabilir . Simdi Helper class ımız orneklendigi zaman dal uzerindeki metotlara helper nesnemizin erismesi icin helper ın yapıcı metotunda dal nesnemizi ornekleyelim ve işlemlerimize başlayalım . class Helper Yukarıdada oldugu gibii Helper nesnemiz örneklendigi zaman dal nesnemizide iceride yani helper nesnemizin yapıcı metotunda ornekledik artık helper üzerinden dal nesnemizin tum public metotlarına erisebilir ve kullana biliriz . Şimdi dal sınıfımızdan gelen urunlerimiz helper katmanında işleyecegimizi söylemiştik peki dal kısmından bana geri donen sqldatareader nesnelerimi ben birer tip uzerine almam gerekmektedir . bu yuzden simdi helper nesnemizi bu sekilde bırakıp 2 adet tip tanımlayalım . Alt Kategori ve Urun adında iki adet tip tanımlayalım ki helper
nesnemiz uzerinde daldan gelen verilerimizi bu tiplerimizi kullanarak depolayalım
. Urun.cs [Serializable] Yukarıdali kısımda fieldlarımızın tanımlamalarını yaptık . public decimal StokTutari
public override string ToString() Cevabını makalemizin ilerleyen kısımlarında
birebir uygulayıp cevaplayalım Yukarıda olusturdugumuz Urun tipimizin icerisinde UrunId – UrunAdı – Renk – Fiyat – Stokmiktarı – StokTutari adında fieldlarımız vardır . Tipimizin erişim belirleyicisi public olup name space düzeyinde [Serializable] olarak işaretlenmiştir . Simdi AltKategori tipimizi oluşturalim ve inceleyelim . class AltKategori Yukarda tipimizde kullanıcagımız degiskenlerimizi olusturduk yalnız burda suna dikkat cekmek istyorum urunler degiskenimizin tipi List<Urun> olarak verilmistir yani tipimiz icerisinde bir list generic atadık bize ayrı ayrı SqlDataReader olarak gelen verilerimizi artık bir tipde MARS destegini kullanarak işleyeceğiz . public AltKategori() this.KategoriId = kategoriid; Kullanıcagımız tiplerimizi oluşturdukdan sonra artık helper sınıfımıza gidip dal sınıfımızdan gelen verilerimizi işleyip tiplerimiz uzerine alalım . Helper.cs devam... Urun tamamla metodumuz metot imzası olarak bizden int tipinden id değeri istemektedir ve geri dönüş değeri List<Urun> seklindedir. { While dongumuz içerisinde urunler adını verdigimiz koleksiyonumuzun
.add metotu ile koleksiyonumuza gelen urunlerimizi doldurmaktayız . doldurma
aşamasında eger database tarafından null olarak donen degerler var ise bunlara
kod kısmında default degerler verip o sekilde koleksiyona atanmasını saglarız
. Yukarıda urunler metotumuzu yazdık ve c# komutlarımızın aralarına girerek açıklamaya çalıştık . Simdi kategorilerimizi çekelim .
Yalnız AltKategori tipimiz en son olarak bizden list<urun> tipinden urun istemektedir . ve biz burada database tarafından gelen bir urun list generic koleksiyon bulamamakdayız . Ilk olarak tamınladıgımız metotumuz olan UrunTamamla metotumuzun geri dönüş parametresi List<Urun> olarak ayarladık ve deger olarak int tipinden id almakda idi . Bu aşamada biz AltKategoriler adındaki list koleksiyonumuza uruntamamla metotumuzu verir ve id olarakda dr.GetInt32(0) kullanarak o Kategorinin id sini veririz. Bu sekilde MARS destegini artık tam anlamı ile kullanmıs oluruz. Aynı anda iki adet SqlDataReader gider bilgileri alır ve AltKategoriTamamla metotumuz kendi icerisinde UrunTamamla metotunu cagırır ve istedigi List<Urun> parametresini alır . } d.ConnectionIslemleri(); Dal tarafında açık bıraktıgımız database baglantımızı artık kapatmamız gerekmektedir . Bunun icin Dal tarafında özellikle tanımladıgımız ConnectionIslemleri adını verdigimiz metotumuzu çağırıp otomatik olarak database baglantımızı kapatırız . return altKategoriler; Yukarıdaki işlemden sonra artık Form Tarafına gecip Dal tarafından aldıgımız Helper kısmında işledigimiz verilerimizi Form katmanında goruntuleyelim . Yalnız form katmanından helper nesnemizin metotlarına ulaşmak için form um yapıcı metotunda Helper nesnemizi örneklememiz gerekmektedir . public partial class Form1 : Form Yukarıdaki şekilde Helper nesnemizi ornekledikden sonra …
Form load kısmında kategorilerimizi doldurmamız gerekmektedir. Bunun icin Form un Load kısmına gidelim ve private void Form1_Load(object sender, EventArgs e) şeklinde listbox ımızın DataSource h.AltKategoriTamamla(); şeklinde
belirtip uygulamamızı çalıştıralım .
Yukarıdada goruldügü gibi uygulamamız çalışmıştır Dal tarafından bilgilerimiz gelmiş Helper katmanında işlenmiş ve form katmanına ulaşmıştır : Makale İcerisinde Sordugumuz Sorumuzun
Cevabı : Peki Neden bu şekilde davrandı uygulama : Uygulama içerisinde oluşturdugumuz tipimiz olan AltKategori tipimizin toString() metotunu override etmedigimiz zaman c# tostring() metotunun default tanımlanmıs degerlerini karsımıza cıkartır bunlarda Namespace ve tip adı şeklindedir. Simdi AltKategori tipimize girip toString() metotumuzu override edelim . public override string ToString() Uygulamamızı Simdi Çalıştıralım . Artık Kategorilerimiz listbox ımız içerisinde Urun adı ve o urune ait toplam sayımızı almış olduk . Makalemiz içerisindeki sorumuzuda cevaplamış olduk . Simdi kategoriler kısmından bir kategoriye tıkladıgımız zaman urun listbox dolmasını sağlayalım . Bunun için lstKategoriler_SelectedIndexChanged event kullanıcağız . private void lstKategoriler_SelectedIndexChanged(object sender,
EventArgs e) lstKategoriler adını verdigimiz listbox ımızın selectedIndexChange event(olay) kullanarak lstUrunler listbox ımızın lstUrunler.Datasource secilen lstKategoriler ( AltKategori ) cast edip bunun uzerinde olan urunler field ımızı veririz. Urunler degerimiz list<urun> tipinde koleksiyon oldugu icin secilen kategorinin id sini alan ve o id e ait urunleri getiren list koleksiyon dur ve urunlerimiz bu sekilde dolmaktadır . Şimdi uygulamamızı tekrar çalıştıralım ve bir kategori secelim urunler listbox ımızın dolmasını sağlayalım . Uygulamamızı çalıştırıp kategorilerden Shorts (7) tıkladıgımız zaman 7 adet urunumuzun urunler kısmında belirdigini gördük burda şuna dikkatinizi çekmek isterim . Urunler dolar iken asla ve asla gidip database tarafından almadık bilgilerimizi olusturdugumuz AltKategori tipimiz icindeki urunler kısmında aldık . Database e bir kere baglandık ve artık tum işlemlerimizi list koleksiyonumuz içerisinde yapmakdayız . Son olarak sectigimiz ürünümüzün ürün bilgilerinin gelmesini saglayalım bunun icin form katmanında ufak bir metot yazalım . public void YerlerineYerlestir(Urun u) YerlerineYerleştir metotumuz metot imzası olarak Urun tipinden parametre kabul etmektedir ve geri donus degeri void ( yoktur ) olarak belirlenmiştir . Metot icerisinde form üzerindeki ilgili textboxlarımıza degerlerimiz atanmıştır . Urunler listbox ımız üzerinden SelectedIndexChanged event ına gidip asagıdaki gibi bilgileri parametre olarak artık metotumuza verelim . private void lstUrunler_SelectedIndexChanged(object sender,
EventArgs e) Metot icerisinde YerlerineYerleştir metotumuzu çagırdık metotumuz bizden urun tipinden parametre istemektedir bizde lsturunler.SelectedItem (Urun) cast ettik ve bu sekilde parametre olarak alınmasını sagladık . Urunler kısmında dolan veri list<Urun> tipinden oldugu icin cast sırasında herhangi bir degisiklik bir uyumsuzluk bulunmamaktadır . Simdi uygulamamızı calıstıralım ve Kategori secelim Urun secelim ve urun bilgisini textboxlarımıza alalım . Uygulamamız artık normal bir sekilde calısmaktadır . Artık urunumuz uzerindeki sepetleme işlemlerine baslayalım ve secitigimiz urunleri almaya baslayalım Alışverişimiz yapalım . Sepetimizi hazırlamak icin ayrı bir sınıf olusturalim ve adına AlinanUrunListesi olark belirleyelim . AlinanUrunListesi sınıfımız aldıgımız urunleri icerde bir koleksiyon ile tutucaktır . class AlinanUrunListesi public void UrunAl(Urun u) Şimdi form uzerindeki olusturdugumuz linklabel Ürünü Satın Al
ın LinkClicked event ını kullanarak urunlerimizi ekleyelim . Helper h; Nesnemizi örnekledikden sonra ilgili olayımıza gidip kodlarımızı yazalım . private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs
e) label12.Text = string.Format("Sepette {0} adet Ürün Wardir",
AlinanUrunListesi.UrunSayisi); Şimdi uygulamamızı çalıştıralım ve biraz alışveriş yapalım :) Alışverişimiz sırasında 10 adet urun aldık artık sepetimizde 10 adet urun bulunmaktadır . Artık sepetimize ürünlerimizi attıgımıza göre gidip sepetimizi goruntuleye biliriz . Sepetimiz icerisindeki urunleri ve toplam fiyatlarını alalım . Sepetimizdeki işlemleri goruntulemek icin yeni bir form olusturalim [form2] Sepetim tıkladıgım zaman sepetimdeki urunlerimiz ve toplam ödeyecegim miktarı ögrenmek icin yeni bir form acmam gerekmektedir . bunun icin Sepetim linklabel uzerinde LinkClicked event ını kullanarak . yeni form umuzun gelmesini saglayalım . private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs
e) Artık yapıcagımız işlemlerimiz Form2 tarafında olucaktır . Form2 inceleyelim . public partial class Form2 : Form Form2 nesnemiz orneklendigi zaman yukarıdaki işlemler olmaktadır . Simdi Form_Load aşamasında sepetimizin oluşmasını icerisine verilerin atanması kısmına bakalm . private void Form2_Load(object sender, EventArgs e)
Form2 load kısmında yani yuklenme asamasında static olarak olusturdugumuz list koleksiyonumuz direk olarak cagrılmaktadır . zaten icinde urun bilgilerini tutugu icin hic bir isleme gerek kalmadan sepetimizi görebiliriz. FiyatTopla metotumuz aşagıdak işlemleri yapmaktadır . public void FiyatTopla() FiyatTopla metotumuz iceride aşagıdaki işlemleri yapmaktadır . • Decimal toplamRakam adında deger tipli bir degisken olusturmaktadır
ve oluşturulma aşamasında 0 olarak deger almaktadır . Deger tipli degiskenlerimiz
bellege bos bir sekilde cıkamazlar o yuzden herhangi bire deger alıp o sekilde
bellekde yerlerini almalıdırlar . Uygulamamızı calıstıralım alısverislerimizi yapalım ve sepetimize
bakalım .
Artık uygulamamızda rahatlık ile alış veriş yapıp istediğimiz ürünümüzü sepetimize aktarabilir ve sepetimizin içerisindeki ürünleri ve toplam fiyatlarını alabiliriz. Bu kısma kadar uygulamamızı tamamladık son olarak şunu düşünelim. Ürünlerimizi şimdi almak istemiyoruz daha sonra alacağız bunun icin sepetimi kaydet link label tıkladığımız zaman gitsin bir yere bu bilgilerimizi binary olarak yazsın ve kaydetsin . public void SepetiKaydet(string path, List<Urun> gelenUrun) Helper sınıfımız icerisinde binary donusturme kodlarımızı yazalım ve Sepeti Kaydet kısında ornekleyip kullanalım . private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs
e) } Yukarıdaki gibi sepetimi kaydet butonuna bastıgımız zaman sepetimiz binary olarak gidip kendini belirledigimiz yere kaydedicektir. Uygulama çalıştıgı zaman eger daha onceden yapılmış ve kaydedilmiş bir sepetimiz var ise bize sorsun desin ki Sepetinizde n adet Urun var yuklemek istermisiniz. Eger sepetimiz yok ise desin ki Bu ilk alışverişiniz . Kodlarımızı Form1 load kısmında yazalım . Uygulama calıstıgı zaman ilk olarak form un yapıcı metotundan sonra load metotu calısıcaktır . Form1_Load Kısmı … Ilk Olarak sepetimizin olup olmadıgına bakalım . public List<Urun> SepetiOku() Yukarıdaki metotumuz içerisinde gelenurun adında list<urun> koleksiyonu olusturduk ve if koşulunu kullanarak dosyamızın var olup olmama durumunu kontrol ettik eger dosyamız var ise filestream ile dosyamızı acıp BinaryFormatter . Deserialize metotu ile binary dosyamızı okuduk . metot imzamızda oldugu gibi list<urun> koleksiyon olarak verilerimizi geri dondurduk . Form load kısmında if (h.SepetiOku().Count!=0 bu kısımda gidip metotumuz calıstırdık
ve coun bilgisini aldık eger 0 a esit degil ise dedik ve eşit olmama durumunda
sepetimize eski sepetimizi atadık . ) Artık eski bir sepetimiz var ise uygulamamız ilk acıldıgı zaman sepetimizi bulucak ve bize sorucaktır evet olarak secer isek eski alışverişimiz yeni sepetimize yuklenecektir. Hayır der isek herhangi bir eskiden kalma alışveris yeni sepetimize yuklenmeyecektir. Eger dosyamızı bulamaz ise else metotu calısıcak ve Bu Ilk AlisVerisiniz olarak bize mesaj vericektir .
Cengiz Atilla
| |
Yazgelistir.com | |