<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Diyezon &#187; .net</title> <atom:link href="http://www.diyezon.com/tag/net/feed/" rel="self" type="application/rss+xml" /><link>http://www.diyezon.com</link> <description>programlama sanatı...</description> <lastBuildDate>Tue, 24 Jan 2012 00:13:26 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Enine Boyuna Generics &#8211; Bölüm 2</title><link>http://www.diyezon.com/enine-boyuna-generics-bolum-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enine-boyuna-generics-bolum-2</link> <comments>http://www.diyezon.com/enine-boyuna-generics-bolum-2/#comments</comments> <pubDate>Sun, 23 Sep 2007 20:24:43 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[.net 2.0]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[generics]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=55</guid> <description><![CDATA[Bir önceki bölümde Generics hakkında bazı terminolojiler üzerinde durduk. Ayrıca ilk başta verdiğimiz örnek ile, bir sınıfı veya bir metodu object yaklaşımı ile nasıl genlleştirilebileceğini gördük. Önceki makaleyi okuduktan sonra objcet yaklaşımı ile Generics arasındaki farkı idrak ettiğinize inanıyorum. Ve Generics&#8217;in avantajlarını ve kolaylığını anladığınızı düşünüyorum. Bu bölümde Sınırlandırıcıları(Constraints) göstermeye çalışacağız. Hazırsanız buyrun. Sınırlandırıcılar(Kısıtlamalar, Constraints) [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Bir önceki bölümde Generics hakkında bazı terminolojiler üzerinde durduk. Ayrıca ilk başta verdiğimiz örnek ile, bir sınıfı veya bir metodu object yaklaşımı ile nasıl genlleştirilebileceğini gördük. Önceki makaleyi okuduktan sonra objcet yaklaşımı ile Generics arasındaki farkı idrak ettiğinize inanıyorum. Ve Generics&#8217;in avantajlarını ve kolaylığını anladığınızı düşünüyorum.</p><p
align="justify">Bu bölümde Sınırlandırıcıları(Constraints) göstermeye çalışacağız. Hazırsanız buyrun.</p><p><span
id="more-55"></span></p><h1>Sınırlandırıcılar(Kısıtlamalar, Constraints)</h1><p
align="justify">Öyle olurki bazen, tip argümanlarınızın belli metodları ve özellikleri içermesini isteyebilrsiniz. Mesela çizim yapma özelliği olan sınıfların kolleksiyonunu tutan bir generic sınıf düşünün. İsmi de TCizebilenKolleksiyon gibi bir şey olsun. Bu generic kolleksiyona atayacağınız her elemanın bir çizim gerçekleştiren &#8220;Ciz&#8221; gibi bir metodunun olmasını isteyebilirsiniz. Bu durumda, tip parametresini belli arayüzler ile sınırlandırmanız gerekmektedir. Bu örneğimizi koda dökecek olursak, arayüzümüz şöyle bir şey olacak:</p><pre>
<pre class="brush: delphi">ICizebilen = interface
public
  procedure Ciz;
end;</pre></pre><p
align="justify">Bu arayüz ile sınırlandırılmış olan kolleksiyon sınıfımız da şöyle bir şey olabilir:</p><pre>
<pre class="brush: delphi">TCizebilenKolleksiyon&lt;T: ICizebilen&gt; = class
...
end;</pre></pre><p
align="justify">Bu durumda T parametresine atayacağımız her argümanın ICizebilen arayüzünün sahip olduğu özellik ve metodlara sahip olacağını garantilemiş oluyoruz.</p><p
align="justify">.Net ortamında kullanabilceğiniz bir çok arayüz bulunmaktadır. Bu arayüzler genelde &#8220;able&#8221; son eki ile biterler. &#8220;able&#8221; ekinin Türkçe karşılığı &#8220;-ebilen&#8221;, &#8220;-abilen&#8221; olarak düşünebilirsiniz.. ISerializable, IComparable, ICloneable, vs&#8230;</p><p
align="justify">Tip parametreleri birden fazla arayüz sınırlandırıcısı alabilir. Bu durumda tip parametreleri virgül yerine aynen prosedür ve fonksiyonların parametrelerinde olduğu gibi &#8220;;&#8221; noktalı virgül ile ayrılırlar. Mesela:</p><pre>
<pre class="brush: delphi">TSinif&lt;T: ISerializable; U: IColoneable&gt; = class</pre></pre><p
align="justify">gibi&#8230; Bu örneğe göre T parametresi ISerializable arayüzünü, U parametresi de IColoneable arayüzünü desteklemesi şarttır.</p><p
align="justify">Ayrıca, birden fazla sınırlandırıcı, tek bir tip parametresine atanabilir. Bu durumda bunlar, &#8220;AND&#8221; lojik mantığına göre tip parametresini sınırlandırırlar.</p><pre>
<pre class="brush: delphi">TSinif&lt;T: ISerializable, IColoneable&gt; = class</pre></pre><p
align="justify">gibi&#8230; Bu örnekte T parametresi hem ISerializable, hem de IColoneable arayüzlerini desteklemek zorundadır. Aynı şekilde prosedür ve fonksiyon parametrelerinde olduğu gibi aynı sınırlandırmaya sahip iki tip parametresini virgül ile ayrırak beraber yazabilirsiniz:</p><pre>
<pre class="brush: delphi">TSinif&lt;T, U: ISerializable&gt; = class</pre></pre><p
align="justify">gibi&#8230; Bu örneğe sınırlandırıcıya sahip olmayan bir parametre daha ekleseydik noktalı virgül ile ayırmamız gerekecekti:</p><pre>
<pre class="brush: delphi">TSinif&lt;T, U: ISerializable; Z&gt; = class</pre></pre><p
align="justify">gibi&#8230;</p><p
align="justify">Bunlar grammer ile ilgili kısımlardı. Peki derleyicinin davranışı nasıl olacak? Aşağıdaki örneğe bakalım:</p><pre>
<pre class="brush: delphi">TPrintableCollect&lt;T: IPrintable&gt; = class ...
...
TDeneme = class(IPrintable)
  procedure Print;
end;

THata = class
end;
...
var
  Calisan: TPrintableCollect&lt;TDeneme&gt;;
  Hatali: TPrintableCollect&lt;THata&gt;; //Syntax hatası: THata sınıfı IPrintable arayüzünü desteklemiyor.</pre></pre><p
align="justify">Gördüğünüzü gibi THata sınıfı IPrintable arayüzüne yabancı olduğu için tip argümanı olarak atadığımızda syntax hatası alıyoruz.</p><p
align="justify">Bununla beraber aynı mantık ile arayüz yerine bir sınıfı sınırlandırıcı olarak kullanabilirsiniz. Bu durumda generic sınıfımız ancak ve ancak sınırlayıcı olarak verdiğimiz sınıf ve alt sınıflarından tipleri alabilir. Mesela:</p><pre>
<pre class="brush: delphi">TBirSinif = class...
TBirAltSinif = class(TBirSinif)...
TBirKolleksiyon&lt;T: TBirSinif&gt; = class...</pre></pre><p
align="justify">Bu örneğimizde T tip parametresine ancak ve ancak TBirSinif ve ondan türeyen sınıflar argüman olarak atanabilir.</p><h2>Sınırlandırıcılarda Belirsizlik</h2><p
align="justify">İki adet sınırlandırıcı, bir tip parametresine atandığını düşünelim. Mesela:</p><pre>
<pre class="brush: delphi">TTest&lt;T: ISerializable, ICloneable&gt; = class
  BirNesne: T;
  procedure Klonla;
end;

procedure TTest&lt;T&gt;.Klonla;
begin
  BirNesne.Clone;
end;</pre></pre><p
align="justify">Derleyici &#8220;BirNesne&#8221; değişkeninin ISerializable ve ICloneable arayüzlerini desteklediğini biliyor. Ayrıca IClonable arayüzünde de Clone isminde bir metod olduğunu da biliyor. Bu yüzden Klonla metodunda Clone metodunu çağırırken herhangi bir çevirim işlemi yapmadık. Çünkü derleyici, Clone metodunun hangi arayüze ait olduğunu biliyor.</p><p
align="justify">Farz edelim ki Clone metodu, hem ISerializable hem de ICloneable arayüzlerinde bulunuyor olsun. Bu durumda Clone metodunu yukarıdaki gibi çağırdığımızda ne olacak? Derleyici bu durumda belirsizilik olduğuna dair bir hata mesajı gösterecektir. Bu belirsizliği ortadan kaldırmak için harici çevirim(explicit casting) yapmalıyız. Yani:</p><pre>
<pre class="brush: delphi">procedure TTest&lt;T&gt;.Klonla;
begin
  ISerializable(BirNesne).Clone;
  ICloneable(BirNesne).Clone;
end;</pre></pre><p
align="justify">Bu durumda, ilk Clone çağırımı ISerializable arayüzü üzerinden, ikincisi ise ICloneable arayüzü üzerinden gerçekleşecektir.</p><h2>Sınırlandırıcı Olarak constructor, class ve record Kullanmak</h2><p
align="justify">Eğer sınırlandırıcı olarak record gibi referansız tipler kullanacaksak bu durumda &#8220;record&#8221; ayrılmış kelimesini kullanıyoruz. Ama dikkat etmemiz gereken konu kullanacağımız tip argümanı nullable yani null değer alabilen bir tipten olmamalı. Mesela string nullable&#8217;dır ama Integer değildir.</p><p
align="justify">Aynı şekilde eğer sınırlandırıcımız sadece referanslı tipler olacaksa bu sefer de &#8220;class&#8221; ayrılmış kelimesini kullanmaktayız. Ayrıca kullanacağımız tip nullable olabilmeli. Yani tip argümanı olarak sınıfların yaninda string gibi nullable tipleri de kullanabiliriz. Bunları şu şekilde örneklendirelim:</p><pre>
<pre class="brush: delphi">TReferansiz&lt;T: record&gt; = class...
TReferansli&lt;T: class&gt; = class...
TBirRecord = record
end;

var
  Hatali1: TReferansiz&lt;string&gt;; //Hatalı, çünkü string nullable,
  Hatali2: TReferansli&lt;Integer&gt;; //Hatalı, Integer referanslı bir tip değil
  Uygun1: TReferansiz&lt;TBirRecord&gt;;
  Uygun2: TReferansiz&lt;Integer&gt;;
  Uygun3: TReferansli&lt;string&gt;; //string nullable bu yüzden uygun.
</pre></pre><p
align="justify">gibi&#8230;</p><p
align="justify">Constructor kelimse ise, sınırlandırıcıda kullanılan sınıfın mutlaka parametresiz bir constructor&#8217;a sahip olmasını şart koşmaktadır. Mesela:</p><pre>
<pre class="brush: delphi">TBirSinif = class
  constructor Create;
end;

TBirBaskaSinif = class

end;

TBirKolleksiyon&lt;T: constructor&gt; = class...
...

var
  Uygun: TBirKolleksiyon&lt;TBirSinif&gt;;
  Hatali: TBirKolleksiyon&lt;TBirBaskaSinif&gt;;</pre></pre><p
align="justify">Bu örnekte Uygun nesnesinde tip argümanı olarak TBirSinif tipini girdik. Ve derleyici bunu kabul etti. Çünkü TBirSinif parametresiz bir constructor&#8217;a sahip ve sınırlandırıcımız için uygun. Fakat Hatali nesnesinde tip argümanımıza girilen TBirBaskaSinif tipi parametresiz bir constructor&#8217;a sahip değil. Bu yüzden derleyici burada hata gösterecektir.</p><h1>Sonuç</h1><p
align="justify">Normalde Delphi.NET derleyicisi, generics ve .net 2.0&#8242;a tam destek vermekle beraber, bir çok bug da içeriyor. Gerçi bu cümleleri yazdığım sıralarda, RAD Studio 2007 daha 1 haftadır piyasada. Şu an bildiğim kadarı ile Rad Studio 2007&#8242;in çıkacak olan update&#8217;inde büyük çoğunlukla derleyici ve asp.net&#8217;deki düzeltmeler bulunacak. Derleyici düzeltmelerinde de pastanın büyük payını generics ile ilgili hatalar alacak. Bu yüzden generics ile uğraşırken &#8220;Internal Error XXXX&#8221; gibi hatalar ile karşılaşırsanız kafanızı duvarlara vurmayın. Çünkü internal error&#8217;lerin hepsi bug olarak kabul edilir. Böyle bir durumla karşılaştığınızda eğer yoksa QC&#8217;ye rapor edebilirsiniz.</p><p
align="justify">Fatih Tolga Ata © 2007</p><h2>Kaynaklar:</h2><ul><li>CodeGear&#8217;ın Delphi Parametrize Tipler ile İlgili Taslak Metinleri</li><li>.NET 2.0 SDK Yardım Dosyası</li><li>Microsoft Visual C# 2005 Step by Step, John SHARP, 2005 Edition</li></ul><p
align="justify"> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/enine-boyuna-generics-bolum-2/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Enine Boyuna Generics &#8211; Bölüm 1</title><link>http://www.diyezon.com/enine-boyuna-generics-bolum-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enine-boyuna-generics-bolum-1</link> <comments>http://www.diyezon.com/enine-boyuna-generics-bolum-1/#comments</comments> <pubDate>Tue, 18 Sep 2007 03:58:02 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[.net 2.0]]></category> <category><![CDATA[generics]]></category> <category><![CDATA[nesne]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=54</guid> <description><![CDATA[Bir iki önceki makalemizde, Delphi gramerine katılan generics ve parametrize tipleri yüzeysel olarak tanıtmıştık. Generics, RAD Studio 2007&#8242; nin çıkması ile artık sadece beta tester&#8217;larını değil, tüm Delphi programcılarını ilgilendiren bir konu olmuştur. Gerçi şu an için sadece .NET ortamında kullanabildiğimiz bu özellik bir sonraki sürümde Win32 için de kullanılabilir bir gramer olacaktır. Başlangıç için [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Bir iki önceki <a
href="http://www.diyezon.com/?p=48">makalemizde</a>, Delphi gramerine katılan <em>generics</em> ve <em>parametrize tipleri</em> yüzeysel olarak tanıtmıştık. Generics, RAD Studio 2007&#8242; nin çıkması ile artık sadece beta tester&#8217;larını değil, tüm Delphi programcılarını ilgilendiren bir konu olmuştur. Gerçi şu an için sadece .NET ortamında kullanabildiğimiz bu özellik bir sonraki sürümde Win32 için de kullanılabilir bir gramer olacaktır. Başlangıç için <a
href="http://www.diyezon.com/?p=48">önceki makalemizi</a> okuyabilir ya da direk buradan başlayabilirsiniz. Zira bu bölümde Generics ile ilgili temel bilgiler vereceğiz.</p><p><span
id="more-54"></span></p><h1>Giriş</h1><p
align="justify">Generics&#8217;i doğru bir şekilde anlayabilmek için, hangi problemleri çözmek için dizayn edildiğini anlamakta yarar var. Bunun için ilk başta temel bir konudan ve bununla ilgili bir problemden bahsedelim.</p><p
align="justify">.Net ortamı için <em>object</em> tipini herhangi bir değer ya da değişken için referans olarak kullanabilirsiniz. Çünkü her bir referans tipi otomatik olarak <em>System.Object</em> sınıfından türetiilir. Delphi&#8217;nin özel tipleri bile .net ortamına geçtiğinde artık birer <em>object </em>olacaktır. Fakat bazı durumlarda <em>explicit casting</em> yapmadan <em>object </em>sınıfına atama yapmak derleyicinin hata üretmesine neden olabilir (Explicit ve Implicit terimlerine yabancı iseniz <a
href="http://www.diyezon.com/?p=52">buradaki makalede</a> ilgili başlığı bulabilirsiniz.). Bunun için <span
style="font-family: Courier New;">AUTOBOX</span> direktifini kullanmamız gerekebilir. Yani aşağıdaki gibi, Delphi&#8217;ye ait özel bir tipi, .NET&#8217;in <em>object</em> tipine <em>implicit </em>olarak atama yaptığımızda derleyici hata üretecektir.</p><pre>
<pre class="brush: delphi">var
  i: Integer;
  o: &amp;amp;Object;
begin
  o := i;</pre></pre><p>Derleyicinin hata üretmemesi için ya <span
style="font-family: Courier New;">AUTOBOX </span>kullanacağız ya da <em>explicit casting</em> uygulayacağız:</p><pre>
<pre class="brush: delphi">var
  i: Integer;
  o: &amp;amp;Object;
begin
  o := &amp;amp;Object(i); //Explicit casting
  {$AUTOBOX ON}
  o := i;</pre></pre><p
align="justify">Buradan çıkardığımız sonuç, her halükarda eğer .Net ortamından söz ediyorsak, ister Delphi tipi olsun ister olmasın, herşey <span
style="font-family: Courier New;">&amp;Object</span> (<em>System.Object</em>) sınıfından türemiştir. Ve bir şekilde tüm tipler, <em>object </em>nesnesine atanabiliyor.</p><p
align="justify">Biz bu bilgiliyi kullanarak sınıflarımızı ve metodlarımızı bir çok noktada <strong>genelleştirebiliriz</strong>. Mesela VCL&#8217;den hatırlayacağınız <em>TList</em> sınıfına benzer bir liste sınıfı hazırlayabilir ve <em>object</em>&#8216;in yukarıdaki anlattığımız özelliği sayesinde içinde istediğimiz tipte nesneler barındırabiliriz. <em>System.Collections</em> alanında bulunan <em>Queue</em>(kuyruk) sınıfı da bu tarz bir yapıya sahiptir(Kuyruğa ilk giren ilk çıkar.). Mesela aşağıdaki örnekte iki farklı tipi <em>Queue </em>nesnesinin bir elemanı yapıyoruz.</p><pre>
<pre class="brush: delphi">uses
  System.Collections, System.Xml;
  ...

{$AUTOBOX ON}
var
  b: TButton;
  s: XmlDocument;
  q: Queue;
begin
  q := Queue.Create();
  b := TButton.Create(nil);
  x := XmlDocument;
  q.Enqueue(b);
  q.Enqueue(x);</pre></pre><p><em>Queue </em>sınıfının <em>Enqueue </em>metodu, kuyruğa yeni bir <em>object </em>eklemeye yarar. <em>Enqueue </em>metodu <em>object </em>tipinde parametre aldığından her çeşit nesne bu metod ile kuyruğumuza eklenebilir. Bu örneğimizde <em>TButton </em>ve <em>XmlDocument </em>tipinde iki farklı nesneyi kuyruğa ekledik. Kuyruktan bir eleman çıkarmak için ise <em>Dequeue </em>metodunu kullanmamız gerekecektir. <em>Dequeue </em>metodu da aynen <em>Enqueue </em>metodu gibi <em>object </em>nesneleri ile çalışır. Yani <em>Dequeue </em>metodunun çıktısı bir <em>object </em>olacaktır. İşte bu noktada, <em>object </em>sınıfının özelliğinden dolayı <em>Queue </em>sınıfı ve bu iki metodu <strong>genel çapta</strong> kullanılabilir bir yapıdadır.</p><p>Yukarıdaki kodlara şunları ekleyip derlemeye çalışalım:</p><pre>
<pre class="brush: delphi">var
  ...
  ...
  cikanB: TButton;
  cikanX: XmlDocument;
begin
  ....
  ....
  cikanB := q.Dequeue; //ilk button girmişti, ilk de o çıkacak.
  cikanX := q.Dequeue;</pre></pre><p
align="justify">Bu kodu derlemeye kalkdığınızda &#8220;Incompatible types&#8230;&#8221; hatasını alacaksınız. Halbuki yukarıda <span
style="font-family: Courier New;">AUTOBOX </span>ile <em>implicit </em>çevirimi aktifleştirmiştik. Peki bu hatayı neden aldık?</p><p
align="justify">Birincisi, <span
style="font-family: Courier New;">AUTOBOX </span>sadece <em>object </em>nesnelerine atama yapılacağında işe yarıyor, <em>object </em>nesneleri başka bir nesneye atama yapılacağında değil. <em>Object </em>sınıfndan türemiş olan bir sınıfın nesnesi <em>object</em>&#8216;e atama yapacağınızda, derleyici bunu otomatik çevirebilir. Ama aksi durumda, <em>object </em>nesnesinin hangi sınıftaki bir nesneye dönüşeceğini kestiremez. Bu durumda <em>explicit</em> çevirim yapmak zorundayız. Bunun için sondaki iki satırı şu şekilde değiştirmeliyiz:</p><pre>
<pre class="brush: delphi">  ...
  cikanB := TButton(q.Dequeue);
  cikanX := XmlDocument(q.Dequeue);
  ShowMessage(cikanX.Name); //&quot;#document&quot;</pre></pre><p
align="justify">Peki kuyruktan çıkış sırasını yanlışlıkla değiştirseydik ne olurdu? Biliyoruz ki, kuyruk&#8217;ta ilk giren ilk çıkar. Yani örneğimize göre ilk olarak button girmişti ve ilk olarak da o çıkacaktır. Bu durumda sıralarını değiştirelim deneyelim:</p><pre>
<pre class="brush: delphi">  ...
  cikanX := XmlDocument(q.Dequeue);
  cikanB := TButton(q.Dequeue);
  ShowMessage(cikanX.Name);</pre></pre><p
align="justify">Bu kod derlenir fakat çalışma anında yanlış yaptığımızı gösteren bir hata alırız. Bu durumda <em>object </em>sınıfının bu genelleştirme özelliğini, bunun gibi yerlerde kullanmak, bir çok yanlışı ve dikkatsizliği de beraberinde getiriyor.</p><p
align="justify"><strong>Genelleştirilmiş </strong>sınıf ve metodlar oluşturmak için kullanılan bu <em>object </em>yaklaşımının diğer bir dezavantajı ise, <em>object </em>sınıfının diğer bir nesneye çevirim yapılması(unbox işlemi ya da unboxing de denilir) yada başka bir sınıfın <em>object </em>sınıfına çevirim yapılması(box ya da boxing yapılması) esnasında gereken ek hafıza ve işlemci zamanıdır. Yani her defasında <em>Enqueue </em>yapıldığında bir nesne <em>object </em>tipine dönüştürülecek ve her <em>Dequeue </em>yapıldığında ise <em>object </em>nesnesinin tipi başka bir nesneye dönüştürülecektir. Bu da ek işlem gücü ve hafızayı gerektirir.</p><p
align="justify">Sınıfları ve metodları genelleştirmede <em>object </em>yaklaşımının belki başka dezavantajlarda sayılabilir ama, bizim işimiz burada generics ve parametrize tipler. <em>Object </em>yaklaşımı kafamızın bir köşesinde yer etmişken, dilerseniz generics yaklaşımına bir göz atalım.</p><h1>Generics ve Parametrize Tipler(Parameterized Types)</h1><p
align="justify">Aslında Delphi programcıları bunu çok uzun süreden beri bekliyorlardı. Belki de .NET 2.0&#8242;a böyle bir özellik gelmeseydi, uzun bir süre daha Delphi böyle bir özellikten yoksun kalacaktı. Borland ya da CodeGear&#8217;ın .NET ortamına yaptığı yatırımları eleştirenler olmuştur. Fakat bu yatırımlar sayesinde hem Win32 hem de .NET üzerinde Delphi bir çok yeniliğe gitmiştir. <a
href="http://www.diyezon.com/?p=53">Buradaki makaleden</a> bu yeni özellikleri kısaca tanıyabilirsiniz.</p><p
align="justify">Gramere ve kullanışına geçmeden önce bir kaç terim üzerinde duralım. Terimler ilk başta kafa karıştırıcı gibi gelse de bu terimleri kullandıkça alışacağınıza inanıyorum. Bu terimleri önce veriyorum çünkü makale içerisinde bu terimler kullanılacak.</p><h2>Terminoloji</h2><p
align="justify"><strong>Parametrize Tip (Parameterized Type:):</strong> <em>Tip Paremetresi</em>ne ihtiyaç duyan bir çeşit tiptir. <em>Generic tip</em>, parametrize tipin daha çok bilinen ismidir. Ama literatürde ikisi de kullanılmaktadır. Aşağıdaki kodda &#8220;<span
style="font-family: Courier New;">Liste&lt;eleman&gt;</span>&#8221; sınıfı, bir <em>parametrize tip</em>tir.</p><pre>
<pre class="brush: delphi">type
  Liste&lt;eleman&gt; = class
    ...
  end;</pre></pre><p
align="justify"><strong>Tip Parametresi (Type Parameter):</strong> Bir <em>parametrize tip</em> veya metod başlık tanımlamasında, <em>parametrize tip</em>in veya metodun <span
style="text-decoration: underline;">kodlarında kullanılacak</span> olan bir tipi ifade eden bir <em>parametre</em>dir. Daha sonra bu parametreye bir <em>tip argümanı</em> bağlanacaktır. Aşağıdaki kodda &#8220;<em>eleman</em>&#8221; bir <em>tip parametresi</em>dir ve sınıfın kodlarında <span
style="text-decoration: underline;">kullanılacak</span> olan bir tipi ifade eder.</p><pre>
<pre class="brush: delphi">type
  Liste&lt;eleman&gt; = class
    ...
  end;</pre></pre><p
align="justify"><strong>Oluşturulmuş Tip (Instantiated Type, Constructed type):</strong> Parametre kümesi tanımlanmış olan bir <em>parametrize tip</em>tir. <span
style="font-family: Courier New;">Liste&lt;Integer&gt;</span> gibi&#8230;</p><p
align="justify"><strong>Tip Argümanı (Type Argument):</strong> &#8220;<em>Oluşturulmuş</em>&#8221; bir tip yapmak için gereken bir çeşit tiptir. Mesela <span
style="font-family: Courier New;">Liste&lt;Integer&gt;</span> bir <em>oluşturulmuş parametrize tip</em> ise, <span
style="font-family: Courier New;">Integer</span> bunun <em>tip argümanı</em>dır.</p><p
align="justify"><strong>Kapalı Oluşturulmuş Tip (Closed Constructed Type):</strong> Bir <em>parametrize tip</em>in tüm parametreleri, <strong>gerçek tip</strong> olan <em>argüman</em>lar ile çözümlenmiş ise bu tipe, <em>Kapalı Oluşturulmuş Tip</em> denir. <span
style="font-family: Courier New;">Liste&lt;Integer&gt;</span> <span
style="text-decoration: underline;">kapalıdır</span>, çünkü <span
style="font-family: Courier New;">Integer</span> <em>tip argümanı</em> <span
style="text-decoration: underline;">gerçek</span> bir tiptir.</p><p
align="justify"><strong>Açık Oluşturulmuş Tip (Open Constructed Type):</strong> Eğer bir <em>parametrize tip</em>in en az bir parametresi bir <em>tip parametresi</em> ise, bu tip bir <em>açık oluşturulmuş parametrize tip</em>tir. Ayrıca eğer <span
style="font-family: Courier New;">Liste&lt;T&gt;</span> parametrize tipinde <em>T</em> parametresi <span
style="text-decoration: underline;">bir sınıfı</span> içeren parametre ise <span
style="font-family: Courier New;">Liste&lt;T&gt;</span> açık oluşturulmuş bir tiptir. İleride örnekler yaptığımızda bu daha da pekişecektir.</p><p
align="justify"><strong>Oluşturma İşlemi (Instantiation):</strong> Derleyici, parametrize tiplerde tanımlı metodlar için gerçek işlem kodunu oluşturur ve kapalı tipler için gerçek virtual metod tablosunu oluşturur. Bu işlem <span
style="text-decoration: underline;">ön derleme</span> esnasında gerçekleşir. Bu işlem Win32&#8242;de <span
style="font-family: Courier New;">*.dcu</span> ve <span
style="font-family: Courier New;">*.obj</span> dosyalarını çıkarırken gereklidir. Fakat .Net ortamında gerekli değildir. Çünkü .Net oluşturulmuş tipler için gerekli tanımlamalara sahiptir. Bu yüzdendir ki, C++&#8217;da template oluşturduğunuzda, derleyici ilk başta template&#8217;li tipleri ayrı ayrı oluşturmak için ön derleme işlemine girişir. Anlaşılan o ki, Delphi&#8217;nin bir sonraki versiyonunda da Win32&#8242;de generics desteği verebilmek için buna benzer bir yönteme gidilecek. Her neyse&#8230;</p><p
align="justify">Bunlar dışında bir kaç terim daha var. Fakat daha fazla kafa karıştırmamak için, o terimleri ayrı başlıklar halinde ileride görelim. Dilerseniz önceden object yaklaşımı ile yaptığımız işlemleri şimdi de generics ile yapmaya çalışalım.</p><h1>Kullanımı</h1><p
align="justify">Kuyruk örneğimizi hatırlayacak olursanız, ekstradan tip çevirim işlemleri yapmıştık. Ayrıca tip güvenliğinin gerekli olduğundan ve bir dikkatsizlikte belli sorunların oluşabileceğinden bahsettik. Ayrıca fazladan gerçekleştirilen object&#8217;den bir başka tipe ve daha sonra da o tipden tekrar object&#8217;e çevirim yapılmasından dolayı(<em>box / unbox</em>), ekstra hafıza ve işlem gücü gerektiğinden bahsetmiştik.</p><p
align="justify">Bütün bunlara gerek duymadan, genelleştirilmiş sınıflar oluşturabilmek için parametrize tipleri ve generic yapısını kullanabiliriz. Generic sınıflar, tip parametresine sahip olduğundan dolayı, sadece <em>object </em>gibi bir tipe bağlı <span
style="text-decoration: underline;">kalmaz</span>. Böylece yukarıda bahsettiğimiz sıkıntıları da bertaraf etmiş oluruz.</p><p
align="justify">.Net 2.0 ile birlikte <em>System.Collections.Generic</em> alan adının altında bir çok yararlı generic sınıf tanımlanmıştır. Aşağıdaki kod parçasında parametrize <em>Queue </em>sınıf ile oluşturulmuş bir <em>Integer </em>kuyruğu ve bir <em>string </em>kuyruğu görmekteyiz.</p><pre>
<pre class="brush: delphi">uses
  System.Collections.Generic;

  ...
  ...

var
  SayiKuyruk: Queue&lt;Integer&gt;;
  YaziKuyruk: Queue&lt;string&gt;;
  Sayi: Integer;
  Yazi: string;
begin
  SayiKuyruk := Queue&lt;Integer&gt;.Create;
  YaziKuyruk := Queue&lt;string&gt;.Create;
  Sayi := 123;
  Yazi := &#039;Deneme&#039;;
  SayiKuyruk.Enqueue(Sayi);
  YaziKuyruk.Enqueue(Yazi);
  ...</pre></pre><p
align="justify"><em> </em></p><p
align="justify"><em> </em></p><p
align="justify"><em> </em></p><p
align="justify"><em> </em></p><p
align="justify">Gördüğünüz gibi, ne bir çevirim işlemi var ne de tipler uyuşuyor mu diye bir endişe&#8230; &#8220;<em>SayiKuyruk</em>&#8221; ve &#8220;<em>YaziKuyruk</em>&#8221; nesnelerinin ikisi de <span
style="font-family: Courier New;">Queue&lt;T&gt;</span> gibi bir <span
style="text-decoration: underline;">parametrize tip&#8217;den oluşturulmuş</span> tipten oluşturulmuştur <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Terimlerimizde hatırlarsanız &#8220;<em>Kapalı oluşturulmuş tip</em>&#8220;ten bahsetmiştik. Derleyici bu örneğimizde <span
style="font-family: Courier New;">Queue&lt;T&gt;</span> tipinden iki adet <span
style="text-decoration: underline;">yeni tip oluşturmuştur</span>. Bunlardan birisi <span
style="font-family: Courier New;">Queue&lt;Integer&gt;</span> ve diğeri ise <span
style="font-family: Courier New;">Queue&lt;string&gt;</span> tipidir. Ve ikisi de <em>kapalı oluşturulmuş</em> bir tiptir. Ayrıca iki tip tamamen bir birinden <strong>bağımsız</strong> iki farklı tiptir!</p><p
align="justify">Bu örnekten ne öğrendik? Özet olarak, bir generic sınıfa atadığımız <em>tip argümanları</em>na göre(<em>Integer, string, vs..</em>) yeni bağımsız bir tip oluşturuyoruz. Ve bu oluşturulan tip, parametre olarak verdiğimiz argümanlara göre işlem yapıyor.</p><p
align="justify">Önceki Queue sınıfı, sadece <em>object </em>tipinde nesneler ile çalşıyordu. Bu sınıftan sadece bir adet vardı ve oluşturduğumuz nesneler hep aynı sınıftan oluşturuluyordu. Ama <em>generic Queue </em>sınıfında ise iş biraz değişiyor. Artık tanımladığımız farklı tip için ayrı bir sınıf oluşturuluyor. Bu yüzden örneğimizdeki <em>SayiKuyruk </em>ve <em>YaziKuyruk </em>nesnelerinin sınıfları aynı değildir! Derleyici her iki <em>tip argümanı</em> için de ayrı ayrı sınıflar oluşturmuştur. Tip argümanları gerçek tipler olduğu için de oluşturulan bu iki sınıf da <em>kapalı oluşturulmuş</em> tip olmuştur.</p><h1>Tanımlanması</h1><p
align="justify">Generic tiplerin tanımlanması kullanımı kadar kolaydır. Delphi&#8217;de sınıflar, interface&#8217;ler ve record&#8217;lar tip parametreleri ile birlikte tanımlanabilirler. Ayrıca metodlar ve prosedürel tipler de parametrize yapılabilir. Aşağıdaki sınıf tanımlamasına göz önüne alalım:</p><pre>
<pre class="brush: delphi">type
  TBirSinif = class
  public
    procedure BirSeylerYap(Parametre: string); overload;
    procedure BirSeylerYap(Parametre: Integer); overload;
    procedure BirSeylerYap(Parametre: Boolean); overload;
  end;</pre></pre><p
align="justify">Sadece bu sınıf ve metodları düşündüğümüzde aynı iş için üç farklı metod tanımlaması yapıyoruz. Ne için? Sadece bir tipin değişmesi yüzünden. Bir de ikinci bir parametre aldığını düşünün. Veya üç, dört&#8230; Ne yapacağız? 4&#8242;ün 3&#8242;lü kombinasyonunu alıp o kadar farklı metod tanımlaması mı yapacağız?</p><p
align="justify">Bunun yerine bu işi derleyiciye bırakıp, biz sadece tipler ile uğraşıyoruz. Yukarıdaki sınıfımızı parametrize olarak yeniden tanımlayalım:</p><pre>
<pre class="brush: delphi">type
  TBirSinif&lt;T, K, L&gt; = class
  private
    FBirOzellik: K;
  protected
    procedure SetBirOzellik(const Value: K);
  public
    procedure BirSeylerYap(Parametre: T);
    property BirOzellik: K read FBirOzellik write SetBirOzellik;
  end;</pre></pre><p
align="justify">Gördüğünüz gibi, <em>Integer string</em> gibi değişkenler yerine sınıfa eklediğim <em>tip parametreleri</em>ni kullanıyorum. Bu parametrize tipimizde 3 adet <em>tip parametresi</em> mevuct. Gerçi bu örnekte sadece ilk ikisini kullanıyoruz.</p><p
align="justify"><em>Bir genel kültür bilgisi mahiyetinde, ek olarak, bu sınıf derlendikten sonra </em><span
style="font-family: Courier New;">TBirGenericSinif`3</span><em> gibi bir şekle girecektir. Eğer tip parametre sayısı 4 olsaydı, son kısım &#8220;</em><span
style="font-family: Courier New;">`4</span><em>&#8221; olacaktı. Bu yüzden derlenmiş assembly&#8217;nizi ya da programınızı reflect ettiğinizde bu tarz şeyler görürseniz şaşırmayın. Her neyse&#8230;</em></p><p
align="justify">Önceden de bahsettiğimiz gibi yukarıdaki <em>TBirSinif </em>sınıfı ile <em>TBirSinif&lt;T, K, L&gt;</em> generic sınıfı birbirinden çok farklı şeylerdir. İsimleri aynı olabilir ama kesinlikle aralarında bir bağlantı yoktur. Aynı şekilde <em>TBirSinif&lt;Integer, string, Boolean&gt;</em> gibi bir <em>kapalı</em> oluşturulmuş sınıf, <em>TBirSinif&lt;string, string, Integer&gt;</em> gibi başka bir <em>kapalı</em> sınıftan çok çok farklıdır ve bağlantıları yoktur. Çünkü derleyici, <em>tip argümanları</em>na göre tipleri tekrar tekrar tanımlamaktadır.</p><h2>Generic Metodlar</h2><p
align="justify">Sınıflar gibi metodlar ve prosedürel tipler de parametrize olarak tanımlanabilir. Mesela:</p><pre>
<pre class="brush: delphi">type
  TBirProsedur2&lt;T&gt; = procedure(Param1, Param2: T) of object;
  TNormalBirSinif = class
    procedure BirProsedur&lt;X&gt;(Param1, Param2: X);
  end;

procedure TNormalBirSinif.BirProsedur&lt;X&gt;(Param1, Param2: X);
begin

end;</pre></pre><p
align="justify">Görüldüğü gibi parametrize olmayan bir tip içinde(<em>TNormalSinif</em>) parametrize bir metod tanımladık. Bunu yaparken aynen sınıflarda olduğu gibi metod isminden sonra tip parametrelerini giriyoruz. Aynı şeyi parametrize olan bir tip içinde de yapabilirdik. Ama burada karar size ait. Eğer generic bir sınıf içinde farklı parametrelerle tanımlamamız gereken metodlar olursa, bu şekilde parametrize edebiliriz. Yani:</p><pre>
<pre class="brush: delphi">type
  TBirSinif&lt;T&gt; = class
    ...
    procedure BirProc&lt;X&gt;(Param1: X; Param2: T);
  end;</pre></pre><p
align="justify">Görüldüğü gibi sınıf tanımlamasında <em>X</em> parametresi tanımlı olmadığı halde, metod tanımlamamızda kullanabiliyoruz. Peki bu gibi bir şeyi nasıl kullanacağız?</p><p
align="justify">Farkında iseniz bir kaç paragraf yukarıda verdiğimiz bir örneğin tam bir çözümlemesini yapmadık. Yani:</p><pre>
<pre class="brush: delphi">type
  TBirSinif = class
  public
    procedure BirSeylerYap(Parametre: string); overload;
    procedure BirSeylerYap(Parametre: Integer); overload;
    procedure BirSeylerYap(Parametre: Boolean); overload;
  end;</pre></pre><p
align="justify">Bu sınıfta &#8220;BirSeylerYap&#8221; metodu overload edilmiştir. Bu sınıfı generic yaparken şu şekilde bir tanımlama yapmıştık:</p><pre>
<pre class="brush: delphi">type
  TBirSinif&lt;T&gt; = class
  public
    procedure BirSeylerYap(Parametre: T);
  end;</pre></pre><p
align="justify">Burada her bir <em>kapalı tip</em> için sadece bir adet metodumuz olabiliyor. Yani mesela <em>TBirSinif&lt;Integer&gt;</em> gibi kapalı bir sınıf içinde sadece bir adet &#8220;<em>BirSeylerYap</em>&#8221; metodu vardır ve sadece <em>Integer </em>tipinde bir parametre almaktadır. Halbuki bizim esas yapmak istediğimiz her bir <em>kapalı sınıf</em> içinde overload yaptığımız tiplerin sınırlandırmasını <span
style="text-decoration: underline;">kaldırmak</span>. Sadece bir çeşit metod yerine birden fazla çeşitte parametre alan metodlarımız olması gerekiyor. Bu yüzden metodumuzu <strong>genelleştirmek </strong>için onu da parametrize ediyoruz:</p><pre>
<pre class="brush: delphi">type
  TBirSinif&lt;T&gt; = class
  public
    procedure BirSeylerYap&lt;X&gt;(Parametre: X);
  end;</pre></pre><p
align="justify">gibi&#8230; Bu şekilde bir metodun, istediğimiz kadar çeşidini overload yapmadan oluşturabiliriz. Mesela:</p><pre>
<pre class="brush: delphi">var
  BirNesne: TBirSinif&lt;Integer&gt;;
begin
  BirNesne := TBirSinif&lt;Integer&gt;.Create;
  BirNesne.BirSeylerYap&lt;string&gt;(&#039;Deneme bir string&#039;);
  BirNesne.BirSeylerYap&lt;Integer&gt;(123);
  BirNesne.BirSeylerYap&lt;Boolean&gt;(True);
  BirNesne.BirSeylerYap&lt;TForm&gt;(Form1);
  BirNesne.BirSeylerYap&lt;TButton&gt;(Button1);</pre></pre><p>gibi&#8230;</p><p
align="justify">Gördüğünüz gibi overload ile kısıtlı sayıda yaptığımız metod tanımlamalarını bu şekilde artırabiliriz. Bu da aynen sınıflarda olduğu gibi, metodlarımızı da genelleştirmemize imkan sağlıyor.</p><h1>Gelecek Bölümde</h1><p
align="justify">Gelecek bölümde Sınırlandırıcıları ya da başka yerlede göreceğiniz tabir ile Kısıtlamalar ya da Constraints tabirlerini göreceğiz. Diğer bölüme geçmek için <a
href="http://www.diyezon.com/?p=55">buraya</a> tıklayabilirsiniz.</p><p
align="justify">Her zamanki gibi yorum ve eleştirilerinizi bekliyorum.</p><p>Fatih Tolga Ata</p><h2>Kaynaklar:</h2><ul><li>CodeGear&#8217;ın Delphi Parametrize Tipler ile İlgili Taslak Metinleri</li><li>.NET 2.0 SDK Yardım Dosyası</li><li>Microsoft Visual C# 2005 Step by Step, John SHARP, 2005 Edition</li></ul> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/enine-boyuna-generics-bolum-1/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Delphi.NET&#8217;in Yeni Oyuncağı &#8220;Class Helper&#8221;</title><link>http://www.diyezon.com/delphinetin-yeni-oyuncagi-class-helper/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphinetin-yeni-oyuncagi-class-helper</link> <comments>http://www.diyezon.com/delphinetin-yeni-oyuncagi-class-helper/#comments</comments> <pubDate>Wed, 01 Aug 2007 13:14:56 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[class helper]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[nesne]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=50</guid> <description><![CDATA[.Net ortamı için sadece Delphi&#8217;de bulunan bir nesne özelliği ile tanışalım bugün, Class Helper(Sınıf Hizmetçisi, Yardımcısı, ya da ne isim verirseniz.). C# kullanıcıları, 2.0 sürümü ile benzer bir tip olan &#34;Partial Type&#34; ile tanıştılar. Ama partial tipler hali hazırda derlenmiş kodlar üzerinde işlem yapamazlar. Ama class helper&#8217;lar yapabilirler! Yani derlenmiş bir assembly&#8217; de bulunan bir [...]]]></description> <content:encoded><![CDATA[<p
align="justify">.Net ortamı için sadece Delphi&#8217;de bulunan bir nesne özelliği ile tanışalım bugün, Class Helper(Sınıf Hizmetçisi, Yardımcısı, ya da ne isim verirseniz.). C# kullanıcıları, 2.0 sürümü ile benzer bir tip olan &quot;Partial Type&quot; ile tanıştılar. Ama partial tipler hali hazırda derlenmiş kodlar üzerinde işlem yapamazlar. Ama class helper&#8217;lar yapabilirler! Yani derlenmiş bir assembly&#8217; de bulunan bir sınıf üzerine de class helper yazılabilir.</p><p
align="justify"> Nedir bu Class Helper? Yenilir mi, içilir mi, grameri nasıldır, ne işimize yarayacak? Bütün bu soruların cevaplarını bu kısa makalemizde vermeye çalışacağız.</p></p><p><span
id="more-50"></span></p><h1>Giriş</h1><p
align="justify">Hemen konuya girelim. Class Helper -yada sınıf hizmetçisi, ya da yardımcısı-, kendisinde bulunan bütün alanlarıyla, yardımcı olduğu sınıfı genişleten bir yapıdır, şeklinde tanımlanabilir. Class helper, mevcut bir sınıfı değiştirmeden veya bu sınıftan yeni bir sınıf türetmeden, bu sınıfa yeni özellikler, metodlar katmaya yarar. Böylece mevcut sınıfta hiç bir müdahaleye gerek kalmadan ve yeni bir sınıf türetmeden, mevcut sınıfımız istediğimiz şekilde şekillenecektir.</p><p
align="justify">Borland bu yapıyı, VCL kütüphanesini .NET ortamına geçirirken ihtiyaç duymuştur. &Ccedil;ünkü Win32&#8242;de tanımlanmış olan bir sınıf, hem .Net&#8217;i desteklemesi lazım hem de mevcut yapısını koruması lazım. İşte class helper, nesne programlamaya böyle bir esneklik getirmiştir.</p><h1>Grameri</h1><p
align="justify">Şimdi bu yapının grameri nasıldır ona bakalım:</p><pre>
<pre class="brush: delphi">TSinif = class
public
  procedure BirProsedur;
end;

TSinifYardimcisi = class helper for TSinif
public
  function BirFonksiyon: Boolean;
end;</pre></pre><p
align="justify">Ardından bu sınıfımızdan bir nesne oluşturalım:</p><pre>
<pre class="brush: delphi">var
  Nesne: TSinif;
begin
  Nesne := TSinif.Create;
  Nesne.BirFonksiyon;
end;</pre></pre><p
align="justify">Farkında iseniz TSinif adlı sınıfımızda &quot;BirFonksiyon&quot; isimli bir fonksiyon bulunmamakta. Ama bir class helper tanımlayarak, olmayan bu fonksiyonu sınıfımıza ekledik.</p><h1>Yanlış Kullanımlar ve Sınırlar</h1><p
align="justify">Nasıl ki programlamada her tekniğin bir yapabildiği olduğu gibi, tekniğe ters olan bazı şeyler de vardır. İlk önce yanlış kullanımlara bakalım:</p><ul><li>Mevcut .NET sınıflarını, kod tanımlamasını değiştirmeden genişletmeye çalışmak.</li><li>Mevcut .NET sınıflarını onlardan miras almadan genişletmeye çalışmak.</li><li>Sealed sınıfları genişletmeye çalışmak. (Sealed sınıflar, sınıf hiyerarşisinde kısır sınıflar olarak bilinirler. Yani sealed sınıflardan herhangi bir başka sınıf türetilemez.)</li><li>Büyük bir sınıf tanımlamasını birden fazla kaynak dosyaya rast gele bir şekilde bölmek.</li></ul><p
align="justify">Her ne kadar bunları yapabilseniz de, tavsiye edilmez ve yanlış kullanım kategorisindedir. Özellikle bir sınıf sealed olarak tanımlanmışsa, bunun elbette bir sebebi vardır. Bunu genişletmek, istenmeyen sonuçlara sebebiyet verebilir.</p><p
align="justify">Yapamayacağınız şeyler ise şunlardır:</p><ul><li>Bir class helper, genişlettiği sınıfın &quot;strict private&quot; olarak tanımlanmış alanına erişemez. Gerçi Delphi programcıları için bu, ne kadar doğru bir sınırlandırma olduğu tartışma konusu olmuştur ve olmaktadır.</li><li>Bir class helper, genişlettiği bir sınıf için interface tanımlayamaz.</li><li>Bir class helper için başka bir class helper tanımlanamaz.</li></ul><p
align="justify">Tabi yapılan en büyük yanlışlıklardan bir tanesi de, class helper&#8217;ları ayrı dosyada tanımladıktan sonra bunları ana sınıfın unitinde implementation alanında değil de interface alanında uses&#8217;a eklemek olacaktır. Bu da çapraz başvurudan dolayı hataya sebep olacaktır. &Ccedil;ünkü eklediğiniz helper unitinde interface alanında zaten uses kısmında ana sınıfın uniti eklenmiş durumdadır. Bu esasen class helper&#8217;larla alakalı bir hata olmadığından yukarıdaki maddelere eklemedim.</p><h1>Faydaları</h1><p
align="justify">Eğer birden fazla kişi aynı sınıf üzerinde çalışıyorsa, class helper&#8217;lar gerçekten çok işe yaramaktadır. Class helper kullanılmadığında, bir çok programcının yazdığı sınıfları bir sınıfta birleştirmek için bir kişinin uğraşması gerekmektedir. Bunu yapacak kişi de her yazılan sınıftaki özellik ve metodlara aşina olması şarttır. Class helper kullanıldığında, her programcı, sınıf içinde kendine ayrılmış kısım ile ilgili bir class helper yazar ve bir unit&#8217;e kaydeder. Geriye kalan sadece bunları uses&#8217;a eklemek ve derlemektir. Derleme işleminde, derleyici bu class helper&#8217;ları mevcut sınıfa ekleyerek birleştirip bir sınıf yapacaktır.</p><p
align="justify">Eğer sınıfınız bazı özel araçlar ile oluşturulmuş ise, class helper kullanarak bu oluşturulmuş olan kodda değişiklik yapmanıza gerek kalmayacaktır. &Ccedil;ünkü bu araç ile bir daha kodu üretmeniz gerektiğinde yazdığınız değişikliklerin kaybolmasına sebep olacaktır. Class helper kullanmadan bu tarz bir koda müdahale etmeniz zordur.</p><p
align="justify">Düşünün ki, ürettiğiniz yazılımın bir kaç versiyonu olacak. Mesela profesyonel, standart, temel(basic) gibi versiyonlarınız olacak. Profesyonel&#8217;de olan özellikler standart&#8217;a göre daha fazla olacak. Standartta olan özellikler de temel versiyona göre daha fazla olacak. Class helper kullanmadığınızda bu versiyonları oluşturmak için ayrı ayrı sınıflar oluşturmalısınız. Bu durumda temel sınıftaki bir özellik veya metodun değişmesi, bug&#8217;ların giderilmesi gibi işlemlerde aynı şeyleri hepsi için tek tek yapmalısınız. Birini birinden türetseniz dahi, mesela temel sınıfı ata sınıf kabul edip, diğerlerini ondan türetseniz dahi bu işinizi görmeyecek hatta daha da sıkıntılı bir duruma sokabilecektir. &Ccedil;ünkü nesnelerin kullanımı esnasında, ister istemez bir çok sorunla yüzleşeceksiniz. Bu sorunları çözmek için ek arayüzler ve sınıflar tanımlamak zorunda kalabileceksiniz. Halbuki class helper kullanıldığında sadece en temel olan sınıfı yazarsınız ve diğer sınıfları class helper olarak tanımlarsınız. Böylece mesela programın temel sürümünü derlemek için profesyonel ve standart class helper&#8217;larını projeden çıkarmanız yeterli olacaktır. Profesyonel sürümünü derleyeceğinizde ilgili class helper&#8217;ı projenize eklersiniz ve her şey bir çırpıda halledilmiş olur.</p><p
align="justify">Belki faydaları daha da artırılabilir. Ama kafanızda bir fikir oluşması için bunlar yeterli.</p><h1>(Güncelleme): Class Helper Önceliği</h1><p
align="justify">Anlatmayı unuttuğum bir kısım şimdi aklıma geldi <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p
align="justify">Diyelim ki şöyle bir sınıf ve class helper olsun:</p><pre>
<pre class="brush: delphi">TSinif = class
private
  procedure MesajGoster;
public
  procedure BirSeylerYap;
end;

TSinifHelper = class helper for TSinif
public
  procedure MesajGoster;
end;</pre></pre><p
align="justify">Gördüğünüz gibi hem sınıfta hem de helper sınıfta da aynı isimde bir metod var. Ama sınıfta private olarak tanımlanmış bir metod, helper&#8217;da public olarak tanımlanmıştır. Peki burada hangisi geçerlidir? &quot;MesajGoster&quot; metodu tetiklendiğinde hangi metod çalıştırılacaktır? Aşağıdaki koda bakalım:</p><pre>
<pre class="brush: delphi">procedure TSinif.BirSeylerYap;
begin
  MesajGoster;
end;</pre></pre><p
align="justify">TSinif&#8217; ta bulunan &quot;BirSeylerYap&quot; metodumuzu bu şekilde yazdık. BirSeylerYap metodu çalıştığında, &quot;MesajGoster&quot; metodunu çağıracak. İşte burada çağrılacak olan daima önceliği fazla olan helper sınıftır. Yani burada TSinif.MesajGoster değil, TSinifHelper.MesajGoster metodu çağrılacaktır. Yani <strong>öncelik daima helper sınıfa aittir</strong>.</p><p
align="justify">Peki iki helper sınıf arasındaki öncelik neye göre belirlenir? Mesela yukarıdaki sınıfa ve helper&#8217;a ek olarak şunu da yazsa idik:</p><pre>
<pre class="brush: delphi">TSinifHelper2 = class helper for TSinif
public
  procedure MesajGoster;
end;</pre></pre><p
align="justify">TSinif isimli sınıfımızın MesajGoster metodu çağrıldığında hangi metod çağrılacaktır?</p><p
align="justify">Bundan önce class helper&#8217;ların daima sınıflardan öncelikli olduğunu gördük. Bu yüzden sınıfı eliyoruz. Diyelim ki TSinifHelper , TSinifHelper2&#8242;den daha önce yazılmış, yani daha yukarıda yazılmış. Bu durumda hangisi en sonra ya da en altta tanımlıysa onun sözü geçer. Yani <strong>en son tanımlanan helper daha önceliklidir</strong>.</p><p
align="justify">Bir öncelik daha kafamızı karıştırabilir. Diyelimki TSinifHelper, untHelper1 adlı dosyada ve TSinifHelper2 ise untHelper2 adlı dosyada. Bu durumda hangisi daha öncelikli olacak? Bu öncelik değeri, aslında bir önceki ile aynı mantıkta. <strong>Hangisi uses kısmında en sonda ise o önceliklidir</strong>.</p></p></p><h1>Sonuç</h1><p
align="justify">Bence, Delphi.NET ile birlikte gelen en iyi özelliklerden birisi class helper&#8217;lar. Özellikle takım çalışmasında büyük bir kolaylık sağlıyor. Sınıfın bir kısmını bir kişi, diğer tarafta sınıfın diğer kısmını yazan kişilerden habersiz görevini yerine getirebiliyor. Belki ilk başta klasik sınıf bilgimizden biraz garip gelebiliyor ama kullandıkça, ne kadar yararlı olduğunu görebiliyoruz.</p><p
align="justify">Sorularınız olduğunda buradaki yorum kısmına ya da delphiturkiye forumlarında Delphi.Net kısmına iletebilirsiniz.</p><p
align="justify">Kolay gelsin.</p></p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/delphinetin-yeni-oyuncagi-class-helper/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Delphi programcıları, Generics ile tanışıyor&#8230;</title><link>http://www.diyezon.com/delphi-programcilari-generics-ile-tanisiyor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphi-programcilari-generics-ile-tanisiyor</link> <comments>http://www.diyezon.com/delphi-programcilari-generics-ile-tanisiyor/#comments</comments> <pubDate>Wed, 25 Jul 2007 08:55:16 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[.net 2.0]]></category> <category><![CDATA[generics]]></category> <category><![CDATA[highlander]]></category> <category><![CDATA[list]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=48</guid> <description><![CDATA[Şu an betası test edilen Highlander sürümünde göreceğimiz generic tipler, aslında c++ programcılarına pek de yabancı olmayan bir terim. .Net 2.0 ile birlikte, managed kodlar generics ile tanıştı. Haliyle Delphi de, highlander sürümü ile birlikte .net 2.0&#8242;ı ve generics&#8217;i destekliyor. Ama IDE ve kod editörü tam manasıyla generics&#8217;e destek vermeyecek. Ama derleyici olarak generics&#8217;in tüm [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Şu an betası test edilen Highlander sürümünde göreceğimiz generic tipler, aslında c++ programcılarına pek de yabancı olmayan bir terim. .Net 2.0 ile birlikte, managed kodlar generics ile tanıştı. Haliyle Delphi de, highlander sürümü ile birlikte .net 2.0&#8242;ı ve generics&#8217;i destekliyor. Ama IDE ve kod editörü tam manasıyla generics&#8217;e destek vermeyecek. Ama derleyici olarak generics&#8217;in tüm özelliklerinden faydalanabileceğiz. Özellikle generics için refactoring bulunmayacak. Ayrıca help insight &#8216;da da generic tipler &quot;&lt;&gt;&quot; şeklinde görünecek. Ayrıca editor, generic tipleri generic tip olarak nitelememekte. Generic tipi ayrı bir sınıf olarak almakta. Her neyse bu gibi sorunlar bir update ile ya da 2008&#8242;in ilk çeyreğinde çıkması beklenen Tiburon sürümünde halledilecektir. Önemli olan generic tipleri derleyici bazında tam olarak kullanabileceğimiz.</p><p>Bütün bunları geçelim ve generic tiplere yabancı olanlar için bir kaç küçük örnek verelim.</p><p><span
id="more-48"></span></p><pre>
<pre class="brush: delphi">TGenericClass&lt;T&gt; = class
private
  FProperty: T;
public
  property AProperty&lt;T&gt; read FProperty write FProperty;
end;</pre></pre><p>Basit bir generic sınıf tanımlaması bu şekilde. Bu sınıfı aşağıdaki gibi kullanabiliriz.</p><pre>
<pre class="brush: delphi">var
  AStringClass: TGenericClass&lt;string&gt;;
  AIntegerClass: TGenericClass&lt;Integer&gt;;
begin
  AStringClass := TGenericClass&lt;string&gt;.Create;
  AIntegerClass := TGenericClass&lt;Integer&gt;.Create;

  AStringClass.AProperty := &#039;Bu bir string&#039;;
  AIntegerClass.AProperty := 456;
end;</pre></pre><p>Burada T parametresi bir tipi ifade etmektedir. İçine koyacağımız tipe göre sınıfımız kendini şekillendirmektedir. İstersek sınıfmızı &lt;T, U&gt; gibi birden fazla tip ile tanımlayabiliriz. Önceden de dediğim gibi eğer fikirlerini değiştirmezlerse highlander sürümünde editör, generic tipleri normal bir tip gibi algılıyor. Yani siz &lt;T, U&gt; gibi tanımladığınız generic sınıfınızı kullanırken iki yerine bir parametre kullanırsanız delphi böyle bir tanımlamanın olmadığından felan bahsedecektir. Ama eksik parametre kullanıldığını söylemesi gerekmektedir. Bu da çok karmaşık uygulamalarda sizi şaşırtabiliyor.</p><p>Aslında generic tiplerin en çok kullanıldığı yerler belki de kolleksiyon tiplerindedir. Mesela:</p><pre>
<pre class="brush: delphi">var
  AStringList: List&lt;string&gt;;
  AStreamList: List&lt;TMemoryStream&gt;;
begin
  AStringList := List&lt;string&gt;;
  AStreamList := List&lt;TMemoryStream&gt;;

  AStringList.Add(&#039;Birinci sıradaki yazı&#039;);
  AStringList.Add(&#039;İkinci sıradaki yazı&#039;);
end;</pre></pre><p
align="justify">Bu List&lt;T&gt; sınıfını kullanabilmek için System.Collections.Generic&#8217;i uses kısmına eklemelisiniz. Yukarıda gördüğünüz işlem Delphi&#8217;de TList ve pointer&#8217;lar ile yaptığımız işlemleri daha basit bir şekilde yapmamıza yarıyor. List dışında, .net kütüphanesi bir çok generic tip barındırmaktadır. Ama şimdilik highlander&#8217;da generic&#8217;lerin nasıl olacağına dair bu kadar bilgi yeterli. Highlander çıktıktan sonra bununla ilgili bir makale buralarda olabilir.</p><p
align="justify">Yorumlarınızı bekliyorum.</p></p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/delphi-programcilari-generics-ile-tanisiyor/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Delphi.NET ve Firebird Bağlantısı</title><link>http://www.diyezon.com/delphinet-ve-firebird-baglantisi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphinet-ve-firebird-baglantisi</link> <comments>http://www.diyezon.com/delphinet-ve-firebird-baglantisi/#comments</comments> <pubDate>Fri, 20 Apr 2007 22:36:17 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[Veritabanı]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[bdp]]></category> <category><![CDATA[data provider]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[firebird]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=38</guid> <description><![CDATA[Bildiğiniz gibi Delphi artık, .Net ortamında hem VCL bileşenlerini hem de normal .Net bileşenlerini kullanmamızı destekliyor. Bu kısa makalemizde Delphi ile, WinForms&#8217;u kullanarak Firebird veritabanına nasıl erişebileceğimizi göreceğiz. Firebird .NET Data Provider Yapacağımız ilk iş buradaki adresten Firebird .NET Data Provider&#8217;ı indirmek olacak. Eğer daha önceden Firebird&#8217;ü indirip kurmamış iseniz, onu da indirip kurmanız gerekmete. [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Bildiğiniz gibi Delphi artık, .Net ortamında hem VCL bileşenlerini hem de normal .Net bileşenlerini  kullanmamızı destekliyor. Bu kısa makalemizde Delphi ile, WinForms&#8217;u kullanarak Firebird veritabanına nasıl erişebileceğimizi göreceğiz.</p><p><span
id="more-38"></span></p><h1>Firebird .NET Data Provider</h1><p
align="justify">Yapacağımız ilk iş <a
href="http://www.firebirdsql.org/index.php?op=files&amp;id=netprovider">buradaki </a>adresten Firebird .NET Data Provider&#8217;ı indirmek olacak. Eğer daha önceden Firebird&#8217;ü indirip kurmamış iseniz, onu da <a
href="http://www.firebirdsql.org/index.php?op=files&amp;id=engine">indirip</a> kurmanız gerekmete. Ben bu makalede farklılık olsun diye embedded tipi veritabanı kullanacağım. Ama server/classic db ile aralarında fazla bir fark yok. Data Provider&#8217;ı indirirken dikkat etmeniz gereken nokta Delphi&#8217;nin desteklediği .net sürümü ile data provider&#8217;ın aynı olması. Bu makalede Delphi 2006 kullanacağım ve Delphi 2006 .Net 1.1 ile çalışıyor. Bu yüzden .Net 1.1 için gerekli olan Data Provider&#8217;ı indirip kurdum.</p><h1>Data Provider&#8217;ı Delphi&#8217;ye Ekleyelim</h1><p
align="justify">Eğer Data Provider&#8217;ı indrip kurmuş iseniz, Firebird assembly&#8217;lerini Delphi&#8217;ye ekleyebilirsiniz. Bunun için menüden Component/Install .NET Components seçeneğini tıklayalım.</p><p><img
width="680" vspace="5" hspace="5" height="445" border="0" src="/wp-content/uploads/Image/post38/firebird1.jpg" /></p><p
align="justify">Listeden FbCommand, FbCommandBuilder, FbConnection, FbDataAdapter bileşenlerini seçelim. Normalde kategori olarak &quot;General&quot; gözükebilr. İsteğe göre daha sonra bu bileşenleri &quot;Firebird&quot; isimli bir kategoriye alabilirsiniz.</p><p
align="justify">Eğer bu bileşenleri göremiyorsanız, kategori kısmına Firebird yazalım ve &quot;Select an Assembly&quot; tuşuna basarak &quot;C:\Program Files\FirebirdNETProvider XXX&quot;altından &quot;FirebirdSql.Data.Firebird.dll&quot; dosyasını seçelim. Bileşenleri seçtikten sonra onaylayıp kapatalım.</p><h1>WinForms ile Örnek Bir Uygulama</h1><p
align="justify">Yeni bir &quot;Windows Forms&quot; uygulaması açalım. Firebird bileşenlerini Bileşen Paletinde belirlediğiniz kategori altında görünecektir. Eğer General kategorisinde ise &quot;Firebird&quot; isminde yeni bir kategori açıp bu kategori altına bileşenleri taşıyabilirsiniz.</p><p><img
width="293" vspace="5" hspace="5" height="341" border="0" src="/wp-content/uploads/Image/post38/firebird2.jpg" /></p><p
align="justify">Form üzerine bir adet FBDataAdapter ekleyelim. Karşımıza Configuration Wizard çıkacak. Next tuşuna basıp diğer sayfaya geçiyoruz.</p><p><img
width="499" vspace="5" hspace="5" height="388" border="0" src="/wp-content/uploads/Image/post38/firebird3.jpg" /></p><p
align="justify">&quot;New Connection&quot; tuşuna basalım. Karşımıza &quot;ConnectionString Editor&quot; gelecek.</p><p><img
width="496" vspace="5" hspace="5" height="301" border="0" src="/wp-content/uploads/Image/post38/firebird4.jpg" /></p><p
align="justify">Database kısmına db dosyasının yolunu girelim. Server Type olarak ben &quot;Embedded&quot; kullandığım için bu şekilde seçtim. Ama siz Superserver/Classic seçebilirsiniz. Eğer benim gibi Embedded Server kullanıyorsanız, fbembed.dll dosyasının ismini değiştirmeden, &quot;C:\Program Files\Borland\BDS\4.0\Bin&quot; klasörü altına fbembed.dll, firebird.conf, firebird.msg, aliases.conf, ib_util.dll, icu***.dll dosyalarını kopyalamalısınız. Ayrıca bu dosyalar proje dosyanızı kaydettiğiniz yerde de bulunmalı. İsteğe göre System32 klasörü de kullanılabilir ama ben bu şekilde tercih ediyorum.</p><p
align="justify">Eğer db içinde Unicode kullanıyorsanız charset için UNICODE_FSS&#8217;i seçmeyi unutmayın. Å?ifre ve kullanıcı adını da girdikten sonra Test tuşu ile bağlantıyı kontrol edebilirsiniz. Eğer bağlatı başarılı ise Accept tuşuna basıp onaylıyoruz.</p><p
align="justify">Bu işlemin ardından Next tuşuna basıyoruz. Dikkat ederseniz, projemize FBConnection1 isminde yeni bir bileşen otomatik olarak eklendi. Sonraki pencerede, &quot;Use SQL Statements&quot; olarak bırakıp Next diyoruz. Bundan sonra SQL cümleciğimizi oluşturabilmemiz için gereken bir ekran geldi. Buraya aşağıdaki gibi bir SQL cümleciği yazıyoruz.</p><pre>
<pre class="brush: sql">SELECT * FROM KISILER</pre></pre><p
align="justify">&quot;Generate Update, Insert, Delete ..&quot; seçeneğini seçersek, sihirbaz bizim için bu sql cümleciklerini de otomatik olarak oluşturacaktır. Ardından Next ve Finish tuşlarına basıp işlemi tamamlıyoruz. Å?u an FbDataAdapter1 ve FbConnection1 form&#8217;a yerleşmiş olmalı.</p><p
align="justify">Å?imdi gerekli olan DataSet bileşenini oluşturalım. FbDataAdapter1 bileşenini ister sağ tuş ile, isterseniz seçtikten sonra object inspector altındaki bölümden &quot;Generate DataSet&quot; seçeneğini seçiyoruz.</p><p><img
width="477" vspace="5" hspace="5" height="438" border="0" src="/wp-content/uploads/Image/post38/firebird5.jpg" /></p><p
align="justify">New bölümüne DataSet nesnemize dsKisiler gibi bir isim veriyoruz. FbConnection1 bileşenimizin ismini dcMyDB, FbDataAdapter1 bileşenini de daKisiler olarak değiştirelim. Eğer önceden oluşturduğunuz bir DataSet&#8217;i kullanacaksanız, Existing bölümünden istediğiniz DataSet nesnesini seçebilirsiniz. Tablo seçim bölümünden örnek veritabanımızda bulunan ve DataAdapter bileşenine girdiğimiz SQL cümlesinde tanımlanan KISILER tablosunu seçiyoruz. Tamam&#8217;a basıp çıkıyoruz.</p><p
align="justify">dsKisiler isminde (ya da sizin belirlediğiniz bir isimde) yeni bir DataSet bileşeni formumuza eklendi.</p><p
align="justify">Bağlantı bileşenlerimiz bu kadardı. Å?imdi bunu test etmek için form üzerine bir adet DataGrid ekleyelim. DataGrid&#8217;i seçelim ve DataSource özelliğini DataSet&#8217;imiz olan dsKisiler olarak değiştirelim. DataMember özelliğini de tablomuz olan &quot;KISILER&quot; tablosunu seçelim. Bu işlemden sonra DataGrid tablomuzun içeriğini göstermeye başlayacaktır.</p><p><img
width="470" vspace="5" hspace="5" height="500" border="0" src="/wp-content/uploads/Image/post38/firebird6.jpg" /></p><h1>BDP ile Firebird Bağlantısı</h1><p
align="justify">Yukarıda yaptığımız işlemler klasik bir ADO.NET bağlantısı idi. Borland, BDP ile ADO.NET&#8217;e yeni çözümler getirmektedir. BDP, bir çok veritabanını ekstra bir data provider gerektirmeden bir çok özellikle beraber kullanmanızı sağlıyor. Yukarıda yaptığımız işlemler için Firebird DataProivder gerekli idi. Ama BDP bağlantılarında ekstra bir data provider&#8217;a ihtiyacınız yok.</p><p
align="justify">Yukarıda yaptığımız veritabanı bağlantısını şimdi BDP ile yapalım.</p><p
align="justify">Yeni bir WinForms uygulaması açalım. Data Explorer&#8217;dan BDP altından Interbase bağlantısına sağ tuşa tıklayalım ve &quot;Add New Connection&quot; seçeneğini seçelim.</p><p><img
width="291" vspace="5" hspace="5" height="272" border="0" src="/wp-content/uploads/Image/post38/firebird7.jpg" /></p><p
align="justify">İsim olarak &quot;MyDB&quot; yazalım ve onaylayalım. Oluştuduğumuz yeni bağlantıya sağ tuş ile tıklayıp &quot;Modify Connection&quot; seçeneğini seçelim. Database bölümünden database dosyamızı seçelim. Test tuşu ile bağlantımızı test edelim. Eğer bağlantı başarılı ise onaylayıp çıkalım.  MyDB bağlantımızın Tables alt bölümünü açarsak bağlantı otomatik olarak açılacak ve veritabanında bulunan tablolar görünecektir.</p><p><img
width="193" vspace="5" hspace="5" height="333" border="0" src="/wp-content/uploads/Image/post38/firebird8.jpg" /></p><p
align="justify">Å?imdi Tables altındaki &quot;KISILER&quot; tablosunu tutup, formumuza sürükleyelim. Eğer aşağıdaki gibi bir hata alırsanız MyDB bağlantısını tekrar düzenleyin ve bu sefer SQLDialect olarak 1 girin.</p><p><font
face="Courier New">&quot;Ambiguous field name between table RDB$RELATION_CONSTRAINTS and table RDB$RELATIONS  RDB$RELATION_NAME&quot;</font></p><p
align="justify">Formumuzda bir adet BdpConnection ve bir adet BdpDataAdepter bilşenleri eklendi. Firebird bileşenlerinde yaptığımız gibi, DataAdapeter bileşenini seçip Object Inspector altından ya da bileşene sağ tuşla tıklayarak &quot;Generate Typed DataSet&quot; seçeneklerini seçin. Gelen pencereyi onaylayıp kapatın. Formumuza DataSet nesnemiz eklenmiş oldu. Bundan sonra önceki örneğimizde olduğu gibi DataGrid&#8217;i bağlayabiliriz.</p><p
align="justify">Bdp&#8217;nin desteklediği bir çok veritabanı için de bağlantı şekli bu şekildedir. Gerek Firebird bileşenlerini kullanın, gerekse BDP kullanın her halükarda, bir adet Connection, bir adet DataAdapter ve bu DataAdapter&#8217;a bağlı olan bir DataSet&#8217;e ihtiyacınız olacaktır.</p></p></p><p><strong>VCL.NET ile Firebird Bağlantısı</strong></p></p></p></p><p
align="justify">Aslında böyle bir şeyden bahsetmeyeceğim. &Ccedil;ünkü VCL.NET bileşenleri içinde Interbase bileşenlerinin aynıları bulunmakta. Eğer VCL kütüphanesinde bulunan Interbase bileşenleri ile Firebird bağlantısı kurmayı biliyorsanız, VCL.NET ile de farklı bir şey yapmayacaksınız.</p><p>Örnek uygulamaların kaynak kodlarını <a
href="http://www.diyezon.com/wp-content/uploads/File/post38/post38_sample.rar">buradan</a> indirebilirsiniz.</p><p> Kolay gelsin.</p><p>Fatih Tolga Ata &copy; 2007</p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/delphinet-ve-firebird-baglantisi/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>ECO Programlamaya Giriş</title><link>http://www.diyezon.com/eco-programlamaya-giris/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=eco-programlamaya-giris</link> <comments>http://www.diyezon.com/eco-programlamaya-giris/#comments</comments> <pubDate>Thu, 25 Jan 2007 16:56:03 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[.net]]></category> <category><![CDATA[Auto Forms]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[ECO]]></category> <category><![CDATA[model]]></category> <category><![CDATA[model tabanlı programlama]]></category> <category><![CDATA[nesne tabanlı programlama]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=22</guid> <description><![CDATA[Günümüzde yazılım şirketleri, karışık ve ağır projelerin altından kalkabilmek için programcı sayısını artırmaktadır. Projede çalışan programcıların sayısı artmakla beraber, aralarındaki iletişim de o nispette azalmaktadır. Bu problemin üstesinden gelebilmek için çeşitli yöntemler geliştirilmiştir. Bu yöntemlerin en etkililerinden bir tanesi de şüphesiz model tabanlı programlamadır. Projede kullanılan yöntemler, algoritmalar, fonksiyonlar ve veritabanları herkesin anlayacağı bir model [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Günümüzde yazılım şirketleri, karışık ve ağır projelerin  altından kalkabilmek için programcı sayısını artırmaktadır. Projede çalışan  programcıların sayısı artmakla beraber, aralarındaki iletişim de o nispette  azalmaktadır. Bu problemin üstesinden gelebilmek için çeşitli yöntemler  geliştirilmiştir. Bu yöntemlerin en etkililerinden bir tanesi de şüphesiz <strong>model tabanlı programlamadır</strong>. Projede kullanılan yöntemler,  algoritmalar, fonksiyonlar ve veritabanları <strong>herkesin anlayacağı</strong> bir model yapısında birleştirilmekte, böylece proje yöneticisi programcıyı,  programcı da proje yöneticisini anlamakta zorluk çekmemektedir. Model  programlamada Borland&#8217;ın raflarına baktığımızda ise yeni gözdesi <strong>ECO </strong>teknolojisini görmekteyiz. Nasılki modeller, karmaşık projeleri daha az  karmaşık hale getirip kolaylaştırıyor, aynen öyle de ECO da, model programlamayı  o denli kolaylaştırıyor. Bu makalemizde ECO&#8217;ya girşi yapıp, <strong>kod  yazmadan</strong> ya da çok az kod yazarak işlerimizi nasıl rahat hallettiğimize  şahit olacağız. Eğer ilginizi çektiyse <strong>devam</strong> edelim.</p><p><span
id="more-22"></span></p><h2>İçindekiler</h2><p> <strong><a
href="#giris">Giriş</a></strong></p><p><strong><a
href="#modeltabanligelistirme">Model Tabanlı  Geliştirme</a></strong></p><p><strong><a
href="#ornekuygulama">Örnek  Uygulama</a></strong></p><p><strong><a
href="#birecomodeliolusturalim">Bir ECO Modeli  Oluşturalım</a></strong></p><p><strong><a
href="#arayuzuecoileiliskilendirmek">Arayüzü ECO ile  İlişkilendirmek</a></strong></p><p><strong><a
href="#verilerinkaliciliginisaglama">Verilerin Kalıcılığını  Sağlama</a></strong></p><p><strong><a
href="#autoforms">Auto Forms</a></strong></p><p><strong><a
href="#sonuc">Sonuç</a></strong></p><p><strong><span
style="font-size: 10pt; font-family: verdana;"></span></strong></p><p><strong><span
style="font-size: 10pt; font-family: verdana;"></span></strong><font
size="2" face="verdana,geneva"><strong></strong></font></p><p><font
size="2" face="verdana,geneva"><strong> </strong></font></p><h1><a
name="giris"></a>Giriş<font
size="2" face="verdana,geneva"><strong> </strong></font></h1><p
align="justify"> Delphi 8 ile  birlikte yeni bir framework ile tanıştık: <strong>ECO&trade;</strong> (<em>Enterprise  Core Object</em>). ECO, model tabanlı geliştirmeye (<em>Model Driven  Development</em>) imkan tanıyan bir platformdur. &Ccedil;ok az kod yazarak, belki <strong>hiç</strong> kod yazmadan uygulama geliştirebildiğimiz bu platform  sayesinde, veritabanları, uygulamalar ve arayüzler kolay bir biçimde entegre  edilip, yönetilebilir. ECO uygulamaları geliştirmek, zaman kazancı ile beraber  üretimin artırılması noktasında size deneyim de kazandıracaktır. Özelikle  yazılım şirketlerinin ve bu sektörde çalışanların <strong>üretim  artırımı</strong> noktasında sorunlarını çözeceği aşikardır.</p><p
align="justify"> Bu makale  serisinde, ilk başta basit olarak modelleme konusuna değinmek istiyorum.  Ardından ECO ile basit bir uygulama geliştirip, ECO hakkında genel bir bilgi  edinmeye çalışacağız. Devam eden konularda ECO&#8217;nun nesne tabanlı programlamayı  ne kadar çok bistelştirdiğini anlamış olacağız.</p><p
align="justify"> Makaleye devam edebilmek  için <strong>asgari </strong>şunlara ihtiyacınız olacak: ECO kurulu olan sürüm 8  veya yukarısı bir Delphi, basit veritabanları kuracak kadar delphi bilgisi ve  ECO&#8217;yu öğrenmek için gereken <strong>istek</strong>.</p></p><h1><a
name="modeltabanligelistirme"></a>Model Tabanlı Geliştirme<strong><font
size="2" face="verdana,geneva"> </font></strong></h1><p><strong></strong></p><p
align="justify">Bir model, bir şeyin <strong>gösterimi </strong>ya da tanımıdır. Mesela bir uçak modeli, gerçek bir uçağı  göstermektedir. Aynen bunun gibi de bir yazılılm modeli, yazılım geliştirme  alanındaki problemleri ve çözümleri özetleyen ve gösteren bir yapıdır. Tabi ki  bir çok yazılım projesi için çok çeşitli modeller geliştirilmesi mümkündür.  Model ayrıca, takım çalışmalarında geliştiriciler arasında <strong>iletişimi </strong>basitleştirir. Böylece büyük projelerde geliştiriciler birbirlerini  anlamak için kaybedecekleri zamanı işlerine vermiş olacaklardır.</p><p
align="justify"> &Ccedil;ok  çeşitli modeller tanımlayarak, karmaşık yazılım sistemlerini problem alanıdaki  görüntü kümeleri olarak ifade edebiliriz. Bu yapıdaki bir modelin dezavantajı  ise, zamanla bir problem tanımını derece derece, metin tanımlamalarından kaynak  kod ve veritabanı şemalarına çevirmemizdir. Ki bunları <strong>sadece </strong>geliştirici ve derleyici anlayabilir. Diğer bir değişle, iş veya  meslek&icirc; anlayıştan derleyici anlayışına dönüştürmedeki problem, her defasında  kodu <strong>değiştirmemiz </strong>olacaktır. Başkaları tarafından yazılmış  kodları anlamak istediğimizde veya anlatmak istediğimizde ise bunları kaynak  koddan iş mantığına <strong>çevirmemiz </strong>gerekecektir.</p><p
align="justify"> ECO, el ile  yapılan bir çok dönüşüm işlemlerini <strong>kaldırmayı </strong>sağlıyor. ECO,  geliştiriciye iş mantığını daha yakından ifade eden bir problemi modellemesine  izin verir. Böylelikle kompleks uygulamaları daha kolay ve  rahat bir şekilde  anlamamıza ve değiştirmemize imkan tanır.</p><p
align="justify"> ECO&#8217;da modelleri oluşturduğumuz  zaman, sınıflara, <strong>İş sınıfları</strong> veya <strong>Alan  sınıfları</strong> olarak isim veririz. &Ccedil;alışma zamanında bunlara <strong>İş  nesneleri</strong> veya <strong>Alan nesneleri</strong> deriz. Bu isimleri  kullanmamızın nedeni, bir işin problem alanındaki nesneleri direk olarak  göstermesidir. Mesela bir okul kayıt uygulamasında, iş sınıfı olarak &quot;Öğrenci&quot;,  &quot;Öğretmen&quot; ve &quot;Ders&quot; olarak tanımlamamız gerekecektir.</p><p
align="justify"> Buraya kadar  anlattıklarımız daha çok soyut açıklamalardı. ECO ve modellemenin mantığını  anlamak için bu kadar bilgi yeter kanaatindeyim. Å?imdi örnek bir uygulamaya  geçip, ECO&#8217; nun nasıl çalıştığına göz gezdirelim.</p></p><h1><a
name="ornekuygulama"></a>Örnek Uygulama<font
size="2" face="verdana,geneva"> </font></h1><p
align="justify"> Bu uygulamamız, basit olarak adres ve  telefonları XML dosyasında tutan bir<strong> adres defteri </strong>olsun.  Uygulamamız aşağıdaki özelliklere sahip olmalıdır:</p></p><ul><li><p><strong>Å?ahıslar </strong>için irtibat bilgilerini tutabilmeli</p></li><li><p><strong>Å?irketler </strong>için irtibat bilgilerini tutabilmeli</p></li></ul><p> Uygulamamız ile ilgili bu problemleri tanımladıktan sonra  uygulamamızı modelleyebiliriz.</p><p
align="center"><img
width="284" vspace="5" hspace="5" height="285" border="0" src="/wp-content/uploads/Image/post22/Model.jpg" /></p><p
align="justify"> Å?ekilde görülen yapı UML(Unified Modeling Language&trade;) diye  isimlendirdiğimiz, modelleri ifade etmemize yardımcı olan bir<strong> modelleme  dilidr</strong>. Å?ekil bize, dikdörtgenlerle ifade edilen <strong>3  sınıfı</strong> göstermektedir. <strong>İrtibat</strong> sınıfı şekilde  gösterilmese de, <strong>abstrac</strong>t(<em>soyutlanmış</em>) bir sınıftır.  Baş tarafında ok bulunan çizgiler, <strong>Å?ahıs</strong> ve <strong>Å?irket</strong> sınıflarının, İrtibat sınıfından <strong>türediğini </strong>göstermektedir. Model bize, aşağıdaki iş kurallarını ifade  etmektedir:</p><table
width="175" cellspacing="1" cellpadding="5" border="1" align="right" style="margin: 5px;" summary=""><tbody><tr><td
bgcolor="#ffcc00" bordercolor="#0000ff"><p><strong>Abstract Sınıflar</strong></p></p><p
align="justify">Bu konu, nesneye dayalı programlama konusu olup,  ilgili makale ve kitaplarda ayrıntılı bilgi bulunabilir. Kısaca bahsetmek gerekirse, bir sınıfın abstract olması demek, o sınıfın metodlarının tanımlamaları alt sınıflarda yapılacak demektir. Bunun birçok faydasından bir faydası şu olacaktır. Aynı özelliğie ve metodlara sahip sınıflar isteniyorsa, her sınıfın tanımlamasında aynı olan bu özellikleri tekrar tekrar oluşturmak yerine, bu özellikleri ve metodları içeren bir abstract sınıf oluşturursunuz. Böylelikle metodların ve özelliklerin tanımlamalarını alt sınıflara bırakmış olursunuz. Bu abstract sınıfdan türeyen bütün sınıflar da kardeş hükmüne geçip aralarındaki geçişler ve atamalar çok rahat bir şekilde halledilmiş olur. Abstraction hakkında daha fazla bilgi için:</p><p
align="justify"> <a
href="http://www.delphibasics.co.uk/Article.asp?Name=Abstract">http://www.delphibasics.co.uk/Article.asp?Name=Abstract</a></p></td></tr></tbody></table><ul><li><p>Bir İrtibat, bir isme, bir telefon numarasına ve bir de adrese sahiptir.</p></li><li><p>Bir İrtibat, Å?ahıs veya Å?irket olmalıdır.</p></li></ul><ul></ul></p><p
align="justify"><p
align="justify"> Problem tanınımızı  ve buna bağlı model yapımızı oluştuduktan sonra yavaş yavaş ilk ECO uygulamamızı  oluşturmaya geçebiliriz. Uygulamayı Delphi 2005 ile yapacağız ama ECO destekli  herhangi bir sürümde kullanabilirsiniz.</p><p
align="justify"> İşe ilk başta bir ECO uygulaması  oluşturmakla başlayalım.</p></p><ul><li><p>Menüden File / New / Other..  seçeneğini seçelim.</p></li><li><p>Karşımıza New Items penceresi çıkacak. Delphi.NET Projects altından <strong>ECO Windows Forms Application</strong> seçeneğini seçelim.</p></li><li><p>Karşımıza New Application penceresi çıkacaktır. Burada uygulamamız için bir  isim verelim ve uygun bir yer seçelim.</p></li></ul><p
align="center"><img
width="405" vspace="5" hspace="5" height="570" border="0" src="/wp-content/uploads/Image/post22/ECONewApp.jpg" /></p><p> Bu adımlardan sonra Delphi, boş bir ECO uygulaması  oluşturacaktır. Project Manager&#8217; a baktığınızda normal Delphi uygulamasından  farklı olarak fazladan <strong>2 dosya</strong> <strong>daha </strong>göreceksiniz. Biri AdresDefteriEcoSpace.pas ve diğeri  CoreClassesUnit.pas.</p><p
align="center"> <strong><img
width="236" vspace="5" hspace="5" height="269" border="0" src="/wp-content/uploads/Image/post22/AdresDefteri_ProjectManager.jpg" /> </strong></p><p><strong>CoreClassesUnit.pas</strong></p><p> Bu unit, ECO  uygulamamızda sınıfları oluşturduğumuz <strong>UML paketidir</strong>. Normalde  daha çok paket oluşturulabilir ama biz bu uygulamada varsayılan olarak gelen bu  paketi kullanacağız.</p><p> <strong>AdresDefteriEcoSpace.pas</strong></p><p> Bu  dosya, uygulamamızın <strong>ECO Space</strong>&#8216;ini tutar. ECO Space,  uygulamamızın <strong>çalışma zamanındaki nesnelerini</strong> tutar. Diğer bir  değişle nesneleri tutan bir <strong>taşıyıcıdır</strong>. Nasıl ki bir nesne,  bir sınıfın <strong>örneğidir</strong>(<em>instance</em>), aynen öyle de bir ECO  Space, <strong>bir modelin</strong> örneğidir. ECO Space tarafından tutulan  nesneler, alanların(<em>domain</em>) özelliklerini ve modelde tanımlı ilişkileri  tutar.</p><p> Bir nesne taşıyıcısı olarak ECO Space, hem iş gören içerik hem de  önbellektir. ECO Space&#8217;in içindeki <strong>Persistence Mapper</strong> denen  bileşen, XML dosyası, RDBMS gibi Persistence Katmanı ile modelde tanımlı  sınıfların arasında bir <strong>kanal</strong> veya bir köprü olarak  kullanılmaktadır. İlerleyen bölümlerde burayı daha iyi kavrayacağız.</p><h1><a
name="birecomodeliolusturalim"></a>Bir ECO Modeli Oluşturalım<strong><font
size="2" face="verdana,geneva"> </font></strong></h1><p><strong></strong></p><p>ECO, modelleme dili olarak  UML&#8217;i kullanır. En çok kullanılan bölümleri Class Diagram ve Object Constraint  Language (OCL) &#8216;dir.</p><p> Å?imdi önceki oluşturduğumuz AdresDefteri  uygulamasına geçelim. ModelView penceresi altından <strong>CoreClasses</strong>&#8216;  a çift tıklayalım. Bundan sonra <strong>modelleme arayüzü</strong> karşımıza  çıkacaktır. Bununla birlikte &quot;Tool Palette&quot; penceresinin de değiştiğini  göreceksiniz.</p><p
align="center"><img
width="600" vspace="5" hspace="5" height="432" border="0" src="/wp-content/uploads/Image/post22/CoreClassDiagram.jpg" /></p><p> Yeni bir sınıf oluşturabilmek için ister Tool Palette&#8217;i  isterseniz de modelleme alanına sağ tuş ile tıklayarak gelen menüyü kullanabiliriz.  Å?imdi Modelleme alanına yeni bir <strong>sınıf </strong>(ECO Class) ekleyelim.  İsim olarak da &quot;İrtibat&quot; girelim. Ne olursa olsun .NET programlamada Türkçe  karakter serbesttir. .NET unicode tabanlı olduğu için Delphi&#8217;de buna uyum  sağlamışa benziyor. Her neyse, bu sınıf seçili iken Object Inspector&#8217;dan <strong>Abstract </strong>özelliğini <strong>True </strong>yapalım. &Ccedil;ünkü bu  sınıfımız Abstract&#8217;dır(soyut). Abstract sınıflar ile ilgili makalenin başlarında  bir açıklama kutucuğu bulabilirsiniz.</p><p
align="center"><img
width="359" vspace="5" hspace="5" height="163" border="0" src="/wp-content/uploads/Image/post22/NewClass.jpg" /></p><p> Oluşturduğumuz bu sınıfa bir <strong>Attribute </strong>(<em>özellik</em>) ekleyelim. Bunun için yeni oluşturmuş olduğumuz  İrtibat sınıfımızı gösteren dörtgene sağ tuş ile tıklayıp <strong>Add /  Attribute</strong> seçeneğini seçelim. Name özelliğine <strong>İsim</strong> (<em>Türkçe karakter serbest</em>) ve <strong>Type</strong> özelliğine de <strong>string</strong> girelim. Sınıfımızın son hali şu şekilde olacaktır.</p><p
align="center"><img
width="365" vspace="5" hspace="5" height="353" border="0" src="/wp-content/uploads/Image/post22/AddAttribute.jpg" /></p><p> Ardından &quot;Telefon&quot; ve &quot;Adres&quot; için de Attribute ekleyelim.</p><p> <strong>Å?ahıs </strong>ve <strong>Å?irket </strong>adı ile iki tane sınıf  daha oluşturalım. Ama bu sınıflar İrtibat sınıfından <strong>türeyeceği </strong>için Abstract özelliğini <strong>False </strong>olarak bırakalım. Å?imdi  aşağıda gösterildiği gibi Å?ahıs sınıfı ile İrtibat sınıfı arasında <strong>ilişki </strong>kuracağız. Bunun için Tool Palette&#8217;de bulunan <strong>Generalization / Implementation</strong> aracını kullanıyoruz.</p><p
align="center"><img
width="590" vspace="5" hspace="5" height="298" border="0" src="/wp-content/uploads/Image/post22/AddRelationShip.jpg" /></p><p> Aynı ilişkiyi Å?irket sınıfı içinde yapalım. Böylelikle Å?irket  ve Å?ahıs sınıfları İrtibat sınıfından <strong>türemiş </strong>sınıflar oldular.  Eğer nesneye dayalı programlama mantığını biliyorsanız bu kısmı çok rahat  anlamışsınızdır. Diğer bir değişle İrtibat sınıfında bulunan bütün özellikler  Å?ahıs ve Å?irket sınıfında da bulunacaktır. Modelimiz en son hali ile şu şekli  alacaktır:</p><p
align="center"><img
width="284" vspace="5" hspace="5" height="285" border="0" src="/wp-content/uploads/Image/post22/Model.jpg" /></p><p> ModelView  penceresine göz gezdirdiğimizde eklediğimiz sınıfları görebiliriz. Ayrıca  CoreClassesUnit altında da bazı sınıfları görebiliriz.</p><p
align="center"><img
width="236" vspace="5" hspace="5" height="397" border="0" src="/wp-content/uploads/Image/post22/modelview.jpg" /></p><p> Görüldüğü gibi iki tip model yapımız var. <strong>Domain  Model</strong> yapısında direk olarak bizim oluşturduğumuz sınıflar mevcut. <strong>Implementation Model</strong> ise, ECO tarafından otomatik olarak kod  üzerinde oluşturulan <strong>gerçek</strong> Delphi sınıflarıdır.</p><h1><a
name="arayuzuecoileiliskilendirmek"></a>Arayüzü ECO ile İlişkilendirmek</h1><p> Modelimizi tamamladığımıza göre kullanıcı arayüzünü hazırlamaya  geçebiliriz.</p><p> <strong>Önemli:</strong> Bu aşamadan sonra projemizi <strong>derlememiz </strong>gerekmektedir. &Ccedil;ünkü arayüz tasarımcısı model  bilgilerini alabilmesi için derlenmesi gerekmektedir. ECO&#8217; nun çalışma düzeneği,  .Net Reflection üzerine kuruludur. Reflection için projemizi derlememiz  gerekmektedir. Å?imdi devam etmeden önce elimizi F9&#8242;a götürelim&#8230;</p><p> Å?imdi  WinForm&#8217; a geçelim. Forma 2 adet button, 3 adet DataGrid ve Enterprise Core  Objects kategorisinden 3 adet ExpressionHandle ekleyelim. Butonlarından birini <strong>btnÅ?irketEkle</strong>, diğerini de <strong>btnÅ?ahısEkle </strong>olarak  isimlendirelim. Text özelliklerini de &quot;Å?ahıs Ekle&quot; ve &quot;Å?irket Ekle&quot; olarak  değiştirelim. ECO uygulaması oluşturma sihirbazı form üzerine bizim  eklediklerimiz dışında bir kaç bileşen ekler. Bunlar arasında <strong>rhRoot </strong>isimli <strong>ReferenceHandle </strong>bileşeninin EcoSpaceType  özelliğini bizim EcoSpace&#8217;imize bağlıyoruz. Yani buraya:</p><pre>AdresDefteriEcoSpace.TAdresDefteriEcoSpace</pre><p> gireceğiz.  Bundan sonra eklediğimiz 3 adet ExpressionHandle bileşenini ayarlamamız  gerekmektedir. Bu bileşenleri <strong>ehİrtibat</strong>, <strong>ehÅ?ahıs </strong>ve <strong>ehÅ?irket </strong>olarak isimlendirelim. Hepsinin <strong>RootHandle </strong>özelliğini biraz önce ayarlamış olduğumuz <strong>rhRoot </strong>yapalım. Å?imdi aşağıda gösterildiği gibi, her bileşenin <strong>Expression </strong>özelliğini kendi sınıfının <strong>allInstance </strong>özelliğine ayarlayalım.</p><p
align="center"><img
width="474" vspace="5" hspace="5" height="411" border="0" src="/wp-content/uploads/Image/post22/oclexpression.jpg" /></p><p> Eğer rhRoot bileşenini doğru bir şekilde  ayarlamadıysanız muhtemelen resimdeki gibi bir sınıf listesini göremeyeceksiniz.  Bir ReferenceHandle bileşeni, tüm ECOSpace&#8217;ler içinde belirli bir EcoSpace&#8217;i <strong>seçmemize </strong>yarar. Bu örneğmizde <strong>EcoSpaceType </strong>özelliği ile AdresDefteri için oluşturduğumuz EcoSpace&#8217;i seçtik.</p><p
align="justify"> Forma eklediğimiz DataGrid bileşenlerine <strong>dgİrtibat</strong>, <strong>dgÅ?ahıslar </strong>ve <strong>dgÅ?irketler </strong>isimlerini verelim. Herbirinin DataSource özelliğini de kendilerine ait  olan ExpressionHandle bileşenine ayarlayalım. Mesela dgİrtibat için DataSource <strong>ehİrtibat </strong>olacak.  Å?imdi btnÅ?ahısEkle düğmesini çalışır  hale getirelim. Bunun için iki seçeneğimiz var. İster <strong>kod  girerek</strong> istersek de <strong>kod girmeden</strong>. İlk başta herhangi  bir kod girmeden herşeyi IDE ile halledelim. <strong>btnÅ?ahısEkle </strong>düğmesinin özelliklerinden <strong>BindingContext </strong>özelliğini <strong>dgÅ?ahıslar </strong>olarak seçelim. Ardından <strong>EcoListAction </strong>olarak düğmeye basıldığında ne gibi bir işlevi olacağını ayarlayalım.  Örneğimizde bu özelliği <strong>Add </strong>olarak seçeceğiz. <strong>RootHandle</strong> özelliği olarak da Å?ahıslar sınıfına bağlı  ExpressionHandle bileşenini seçelim yani bu örnek için <strong>ehÅ?ahıslar</strong>.   Gördüğünüz gibi kod girmeden işlerimjizi  hallettik. Å?imdi de <strong>btnÅ?irketEkle </strong>düğmesini kod girerek  yapalım. Düğmenin <strong>OnClick </strong>olayına şu kodları ekleyelim:</p><pre>
<pre class="brush: delphi">procedure TWinForm.btnÅ?irketEkle_Click(sender: System.Object; e:  System.EventArgs);
begin
  Å?irket.Create(EcoSpace);
end;</pre></pre><p> Eğer eksik bir şey yapmadıysak  programı çalıştırdığımızda 2 düğmemiz de ekleme işlemlerini  yapacaktır.</p><p><strong></strong></p><p><strong></strong></p><p
align="center"><img
width="360" vspace="5" hspace="5" height="354" border="0" src="/wp-content/uploads/Image/post22/AdresDefteri.jpg" /></p><h1><a
name="verilerinkaliciliginisaglama"></a>Verilerin Kalıcılığını Sağlama</h1></p><p> Buraya kadar yaptığımız  işlemler ile programımız çalışır hale geldi. Fakat eklediğimiz veriler <strong>hafızada </strong>tutuluyor ve program kapatıldığında da hafızadan <strong>siliniyor</strong>. Å?imdi bu verileri bir XML dosyasına yazarak <strong>kalıcı </strong>hale getirelim.</p><p> ECO ile beraber 2 basit <strong>kalıcılığı sağlayan</strong>(persistence) metod bulunmaktadır. Bu  metodlardan birisi XML dosyalarına kaydederken diğeri de RDBMS&#8217;e kayıt yaparken  kullanılmaktadır. Bu örnekde daha basit ayarlandığından dolayı XML dosyalarında  kalıcılık gösterilecektir.</p><p> ProjectManager&#8217;dan AdresDefteriEcoSpace.pas  dosyasına çift tıklayalım. Açık değilse Design kısmına geçip, Enterprise Core  Object kategorisinden <strong>PersistenceMapperXML </strong>bileşenini  ekleyelim. Bu bileşenin ismine <strong>pmXML </strong>ve <strong>FileName </strong>özelliğine de bir dosya ismi yazalım mesela &quot;veri.xml&quot;. Eğer Object  Inspector&#8217;da EcoSpace&#8217;imizin <strong>PersistenceMapper </strong>özelliğine göz  atarsak, otomatik olarak yeni eklemiş olduğumuz <strong>pmXML </strong>bileşenine ayarlandığını görebiliriz.</p><p
align="center"><img
width="491" vspace="5" hspace="5" height="463" border="0" src="/wp-content/uploads/Image/post22/persistence.jpg" /></p><p> Å?imdi WinForm&#8217; a geri dönelim ve bir button ekleyelim.  Button&#8217;nun ismine btnKaydet, ve Text özelliğine de Kaydet girelim. Burada yine  iki seçeneğimiz bulunakta. İster kod girerek istersek de kod girmeden kaydetme  işlemini yapabiliriz. Kod girmeden yapabilmek için Button&#8217; nun <strong>EcoAction </strong>özelliğini <strong>UpdateDatabase </strong>olarak değiştirelim.  Programı çalıştırıp yeni bir kayıt ekleyelim ve kayıt tuşuna basalım. Hepsi bu  kadar. Programın bulunduğu klasörde xml dosyamızı görebiliriz. Ayrıca her  programı çalıştırmada ECO, otomatik olarak xml dosyasını tekrar yükleyecektir.  Eğer kod girerek yapmak istersek, sadece button&#8217;nun onClick olayına şu kodu  yazmamız yeterli olacaktır:</p><pre>EcoSpace.UpdateDatabase;</pre></p><h1><a
name="autoforms"></a>Auto Forms<font
size="2"> </font></h1><p> En son olarak bu  bölümde Auto Form&#8217; lardan da bahsetmek istiyorum. ECO Shiribazı ile oluşturmuş  olduğumuz programımıza otomatik olarak eklenen bileşenler arasında <strong>ECOAutoForms </strong>bileşenini görebilirsiniz. Bu bileşen sayesinde  aşağıda görüldüğü gibi DataGrid üzerine çift tıkladığımızda, ECO bizim için bir  düzenleme formu çıkaracaktır. Bu özelliği aktifleştirmek için, herhangi bir  DataGrid&#8217;in <strong>EcoAutoForm </strong>özelliğini <strong>True </strong>yapmamız yeterlidir.</p></p><p
align="center"><img
width="397" vspace="5" hspace="5" height="415" border="0" src="/wp-content/uploads/Image/post22/AutoForms.jpg" /></p><h1><a
name="sonuc"></a>Sonuç<font
size="2" face="verdana,geneva"> </font></h1><p> Bu bölümde Model Driven  Development kavramını, ECO&#8217; nun OOP ve model programlamaya getirdiği  kolaylıkları, basit bir ECO programının yapılışını görmeye çalıştık.  İlerleyen  bölümlerde ECO ile daha çok haşir neşir olacağız.</p><p> Bu makalde yaptığımız  örnek programın kodlarını <a
href="http://www.diyezon.com/wp-content/uploads/File/post22/AdresDefteri.rar">buradan</a> indirebilirsiniz. Ama  kaynak kodları sadece takıldığınız yerlerde bakmak şartıyla  indirebilirsiniz. <img
src="/wp-content/plugins/editormonkey/fckeditor/editor/images/smiley/msn/teeth_smile.gif" /></p><p> Bu bölüm için bir kaç kaynaktan yararlandım. Başta Delphi  2005&#8242;in Help&#8217;i çok işimi gördü. Bununla birlikte makalenin taslağı  olarak(başlıklar ve konu) Bdn&#8217; deki bir makaleyi örnek aldım. Ama bu makale,  onun çevirisi değildir.  Makalenin adresi aşağıda bulunmaktadır:</p><p> <a
href="http://www.borland.com/us/products/delphi/tutorial/tutorial1.html">http://www.borland.com/us/products/delphi/tutorial/tutorial1.html</a></p><p> Makale  ile ilgili yorum, eleştiri ve sorularınızı bekliyorum.</p><p>Fatih Tolga Ata &copy; Eylül 2005</p><p>Son Güncelleme: 25 Ocak 2007</p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/eco-programlamaya-giris/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Database Caching 1/31 queries in 0.052 seconds using memcached
Object Caching 632/698 objects using memcached

Served from: www.diyezon.com @ 2012-02-08 11:10:26 -->
