<?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; delphi.net</title> <atom:link href="http://www.diyezon.com/tag/delphinet/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>Delphi 7 ile Şimdiki Delphi Sürümleri Arasındaki Farklar</title><link>http://www.diyezon.com/delphi-7-ile-simdiki-delphi-surumleri-arasindaki-farklar/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphi-7-ile-simdiki-delphi-surumleri-arasindaki-farklar</link> <comments>http://www.diyezon.com/delphi-7-ile-simdiki-delphi-surumleri-arasindaki-farklar/#comments</comments> <pubDate>Mon, 13 Aug 2007 22:00:48 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[abstract]]></category> <category><![CDATA[class helper]]></category> <category><![CDATA[class static]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[final metodlar]]></category> <category><![CDATA[fonksiyon]]></category> <category><![CDATA[for-in]]></category> <category><![CDATA[inline]]></category> <category><![CDATA[miras]]></category> <category><![CDATA[nesne]]></category> <category><![CDATA[nested classes]]></category> <category><![CDATA[operator overloading]]></category> <category><![CDATA[property]]></category> <category><![CDATA[record]]></category> <category><![CDATA[sealed]]></category> <category><![CDATA[sınıf]]></category> <category><![CDATA[strict private]]></category> <category><![CDATA[strict protected]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=53</guid> <description><![CDATA[Bildiğiniz gibi VCL, .NET ortamına taşınırken derleyici bazında bir çok değişikliğe ve geliştirmeye gidildi. Bu geliştirmeler, hem Delphi.NET derleyicisini hem bildiğimiz klasik Delphi for Win32 derleyicisini etkiledi. Tabi bu geliştirmeler, en çok biz programcıların işine yaradı. Bu makalemizde bu yeniliklere değinmeye çalışacağız. Bunlardan bir kısmını önceki makalelerimizde ayrıntılı olarak işlemiştik. Burada sadece bu sitede bahsetmediğimiz [...]]]></description> <content:encoded><![CDATA[<p
align="justify">Bildiğiniz gibi VCL, .NET ortamına taşınırken derleyici bazında bir çok değişikliğe ve geliştirmeye gidildi. Bu geliştirmeler, hem Delphi.NET derleyicisini hem bildiğimiz klasik Delphi for Win32 derleyicisini etkiledi. Tabi bu geliştirmeler, en çok biz programcıların işine yaradı.</p><p
align="justify">Bu makalemizde bu yeniliklere değinmeye çalışacağız. Bunlardan bir kısmını önceki makalelerimizde ayrıntılı olarak işlemiştik. Burada sadece bu sitede bahsetmediğimiz kısımlar bahsedilecek ve önceden bahsettiklerimize linkler içerecektir.</p><p><span
id="more-53"></span></p><h1>Operator Overloading:</h1><p
align="justify">Buradaki makalede ayrıntılı olarak işlenmiştir: <a
href="http://www.diyezon.com/?p=52">http://www.diyezon.com/?p=52</a></p><h1>Inline Belirleyicisi:</h1><p
align="justify">Derleyiciye tavsiye niteliğinde olan bu belirleyici (ya da direktif), fonksiyon ya da prosedürün kod çıktısında, çağrıldığı yere gömülmesini sağlar. Tavsiye niteliğinde diyorum çünkü, eğer prosedür ya da fonksiyon inline yapılmaya müsait değilse derleyici bu direktifi es geçecektir.</p><p
align="justify">Inline yapılmış prosedür ya da fonksiyon, &quot;call&quot;, &quot;ret&quot; gibi assembler komutlarına ihtiyacı olmadığı gibi, stack&#8217;ın push ve pop ile yedeğinin de alınmasına ihtiyaç yoktur. &Ccedil;ünkü inline yapılan fonksiyon, direk olarak çağrıldığı kısma yerleşecektir. Halbuki normal fonksiyonlarda call komutu ile hafızada başka bir kod kısmına dallanmaktadır. Ve burada stack&#8217;ın yedeği alınıp, fonksiyon sonunda yedek tekrar yüklenmektedir. Daha fazla bilgi için (<a
href="http://www.diyezon.com/?p=45">Delphi ve C++ Builder ile Assembler</a> ve <a
href="http://www.diyezon.com/?p=47">Fonksiyon &Ccedil;ağırım Mekanizmaları</a>).</p><p
align="justify">Inline prosedür ve fonksiyonda bu gibi işlemler yapılmadığından kod daha hızlı çalışacaktır. Ama her fonksiyon çağırımında fonksiyon kodları direk olarak çağrıldığı yere yerleşeceğinden, programınızın boyutu biraz büyüyecektir. Tanımlaması normal fonksiyon ve prosedür gibi olup sadece son tarafa inline belirleyicisi eklenir:</p><pre>
<pre class="brush: delphi">procedure MyProc(x:Integer); inline;
begin
    // ...
end;</pre></pre><h1>Strict Private</h1><p
align="justify">Sınıf kavramına katılan bu alan tipi, normal private alan gibidir. Tek fark bu alan daha da gizlidir <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Bu dediğimizin anlaşılabilmesi için private alanın ne olduğu bilinmesi gerek. Tabi ondan önce sınıfların ne olduğunu biliyorsunuzdur umarım(<a
href="http://www.diyezon.com/?p=40">Bileşen Yazım Klavuzu</a>nun ilk bölümleri sınıfları anlatmaktadır).</p><p
align="justify">Private sınıflar normalde, aynı unit içindeki başka sınıflar içinden erişilebilir. Strict Private ise gerçekten gizler. Yani aynı unit içinde bile olsa başka bir sınıf strict private alana erişemez.</p><h1>Strict Protected</h1><p
align="justify">Private için geçerli olan durumun aynısı protected için de geçerlidir. Strict Protected ise sadece aynı sınıf ve sınıfın çocukları tarafından görülebilirler. Aynı unit bile olsa başka bir sınıf bu alanı göremez.</p><h1>Metodlu Record&#8217;lar</h1><p
align="justify">Artık Recordlar için private, public gibi alanlar tanımlayıp procedure, function, constructor gibi metodlar tanımlayabiliyoruz. Ayrıca property&#8217;ler de tanımlanabiliyor. Yani aynı sınıflar gibi&#8230;</p><pre>
<pre class="brush: delphi">type
  TMyRecord = record
    type
      TBirTip = Integer; //tip tanımlaması
    var
      BirAlanDegiskeni: TColor;
    class var
      StatikDegisken: Integer;
    procedure BirProsedur();
    constructor Create;
    property Color: TColor read BirAlanDegiskeni write BirAlanDegiskeni;
    class property StatikOzellik: TBirTip read StatikDegisken write StatikDegisken;
  end;

constructor TMyRecord.Create;
begin

end;

procedure TMyRecord.BirProsedur;
begin
  ShowMessage(IntToStr(Color));
end;</pre></pre><h1>Abstract ve Sealed Sınıflar</h1><p
align="justify">Önceden abstract sınıf tanımlanamıyordu. Bunun yerine interface&#8217;ler kullanılıyordu. Ama bu her zaman işe yaramayabiliyor. Yabancı olanlar için kısaca abstract, kendisinde herhangi bir tanımlama ve kod bulunayan, <strong>kod kısmı</strong>, sınıflar için çocuk sınıflarda, metodlar için ise mirasçı metodlarda tanımlı olan bir yapıdır.</p><pre>
<pre class="brush: delphi">type
  TAbstractClass = class abstract
    procedure SomeProcedure;
end;</pre></pre><p
align="justify">Bu sınıfın kod tanımlaması TAbstractClass sınıfından türeyecek olan sınıflarda yapılacaktır.</p><p
align="justify">Sealed sınıflar ise, kısır sınıflardır. Yani artık sınıf hiyerarşisinde en sonda bulunan ve kendisinden herhangi bir türetme yapılamayacak olan sınıflardır.</p><pre>
<pre class="brush: delphi">type
  TSealedClass = class sealed
    procedure SomeProcedure;
end;</pre></pre><p
align="justify">Bu sınıftan başka bir sınıf türetilemez.</p><h1>Class Helper&#8217;lar</h1><p
align="justify">Buradaki makalede ayrıntılı olarak işlenmiştir: <a
href="http://www.diyezon.com/?p=50">http://www.diyezon.com/?p=50</a></p><h1>Class Statik Tipler, Değişkenler, Özellikler, Sabitler, Metodlar</h1><p
align="justify">Bazen olurki nesneyi tanımlamadan, sınıf içinde bulunan bazı değerlere erişilmesini istersiniz. Bu durumda erişilmesini istediğiniz şeyi, statik olarak tanımlamalısınız. Mesela aşağıdaki örneğe bakalım:</p><pre>
<pre class="brush: delphi">type
  TAClass = class
    strict private
      class var
        StatikDegisken: Integer;
    strict protected
      class function GetStatikOzellik: Integer; static;
      class procedure SetStatikOzellik(val: Integer); static;
    public
      class property StatikOzellik: Integer read GetStatikOzellik write SetStatikOzellik;
  end;

TAClass.StatikOzellik := 879;</pre></pre><p
align="justify">Burada gördüğünüz gibi TAClass sınıfından bir nesne oluşturmadan içindeki bir özelliğie eriştik. Class Static tekniğini kullanırken dikkat etmeniz gerken bir kaç önemli nokta şudur:</p><ul><li>Statik metod&#8217;lar içinde artık Self değişkenini kullanamazsınız. &Ccedil;ünkü sınıfa referans içeren bir nesne yoktur.</li><li>Statik metodlar ve özelliklerde ancak ve ancak statik olan değişken ve metodları kullanabilirsiniz.</li><li>Statik metodları virtual ya da dynamic olarak tanımlayamazsınız.</li></ul><p
align="justify">Bunun dışında bir sınıf içinde statik sabitler ve statik tipler de oluşturulabilir:</p><pre>
<pre class="brush: delphi">type
  TBirClass = class
  private
    type
      TBirStatikRecord = record
        BirAlan: string;
      end;
  public
    class var
      BirStatikRecord: TBirStatikRecord;
    const StatikSabit = &#039;Burada class kelimesini kullanmanıza gerek yok!!&#039;;
  end;

....
ShowMessage(TBirClass.StatikSabit);</pre></pre><p
align="justify">gibi&#8230;</p><h1>İç içe Geçmiş Sınıflar &#8211; Nested Classes</h1><p
align="justify">Artık bir sınıf tanımlamasının içinde başka bir sınıf tanımlanabiliyor:</p><pre>
<pre class="brush: delphi">type
  TDistakiSinif = class
  public
    type
      TIctekiSinif = class
      public
        procedure IctekiMetod;
      end;
      procedure DistakiMetod;
  end;

procedure TDistakiSinif.TIctekiSinif.IctekiMetod;
begin
  ...
end;</pre></pre><h1>Final Metodlar</h1><p
align="justify">Sealed sınıflar gibi final metodlar da bir sınıfın çocuk sınıflarında, final olarak tanımlanmış olan virtual metodun miras  alınamadığını ifade eder. Mesela:</p><pre>
<pre class="brush: delphi">TSonMetodluSinif = class(TBirAtaSinif)
public
  procedure SonMetod; override; final;
end;</pre></pre><p
align="justify">Bu tanımlamadan sonra artık SonMetod isimli metod, &quot;TSonMetodluSinif&quot; isimli sınıfın çocuk sınıfları tarafından override yapılamayacaktır. Final metodların sadece virtual metodlarda işe yaradığına dikkat edin.</p><h1>For-In Döngüsü</h1><p
align="justify">Artık bir dizi veya kolleksiyon içinde for-in döngüsü ile iterasyon yapılabilmekte:</p><pre>
<pre class="brush: delphi">
for DiziElemani in BirDizi do
begin
  ....
end;

for BirKarakter in BirString do
begin
  ...
end;

for BirKumeElemani in BirKume do
begin
  ...
end;

for BirKolleksiyonElemani in BirKolleksiyon do
begin
  ...
end;</pre></pre><h1>Sonuç</h1><p
align="justify">Yeni gelen özelliklerin unutmamış isem tamamına değinmeye çalıştım. Bunlara ek olarak Highlander çıktığında generic yani parametrize tiplere de ayrı olarak değineceğiz. Generics&#8217;in nasıl bir şey olduğunu merak edenler <a
href="http://www.diyezon.com/?p=48">buraya</a> tıklayarak meraklarını giderebilirler.</p><p
align="justify">Bunlarla ilgili uygulama yapıp geliştirmek sizlere kalmış. Buradaki bilgiler önfikir mahiyetindedir. Derleyici bazındaki yenilikler bunlar olmakla birlikte, VCL ve diğer alanlarda da bir çok yeniliğe gidilmiştir. Yeri geldikçe bunlardan da bahsedebiliriz.</p><p
align="justify">Yorumlarınız önemlidir, bekliyorum.</p></p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/delphi-7-ile-simdiki-delphi-surumleri-arasindaki-farklar/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Delphi ve Operator Overloading</title><link>http://www.diyezon.com/delphi-ve-operator-overloading/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphi-ve-operator-overloading</link> <comments>http://www.diyezon.com/delphi-ve-operator-overloading/#comments</comments> <pubDate>Sun, 05 Aug 2007 22:00:40 +0000</pubDate> <dc:creator>Fatih Tolga Ata</dc:creator> <category><![CDATA[Delphi]]></category> <category><![CDATA[delphi.net]]></category> <category><![CDATA[nesne]]></category> <category><![CDATA[operator overloading]]></category> <category><![CDATA[sınıf]]></category><guid
isPermaLink="false">http://www.diyezon.com/?p=52</guid> <description><![CDATA[&#34;Operator Overloading&#34;(operator aşırı yükleme), Delphi&#8217;ye Delphi.NET ile birlikte gelen class helper&#8217;lar gibi yeni özelliklerden birisidir. Bu teknik, class helper&#8217;lar gibi hem Win32 hem de .NET için kullanabilirsiniz. Delphi&#8217;ye, belki de çok uzun zaman önce eklenmesi gereken bu özellik ile, herhangi bir sınıf veya record için toplama(+), çıkarma(-), çarpma(*) gibi operatörlere bazı özel anlamlar yükleyebiliyoruz. C++ [...]]]></description> <content:encoded><![CDATA[<p
align="justify">&quot;Operator Overloading&quot;(operator aşırı yükleme), Delphi&#8217;ye Delphi.NET ile birlikte gelen class helper&#8217;lar gibi yeni özelliklerden birisidir. Bu teknik, class helper&#8217;lar gibi hem Win32 hem de .NET için kullanabilirsiniz.</p><p
align="justify">Delphi&#8217;ye, belki de çok uzun zaman önce eklenmesi gereken bu özellik ile, herhangi bir sınıf veya record için toplama(+), çıkarma(-), çarpma(*) gibi operatörlere bazı özel anlamlar yükleyebiliyoruz. C++ programcılarının hiç de yabancı olmadıkları bu teknik ile kendimize özel veri tipleri tanımlayıp, bu tiplerin Integer, string gibi başka tipler ile etkileşimlerinin nasıl sonuç vereceğini belirleyebilirsiniz.</p><p><span
id="more-52"></span></p><h1>Giriş</h1><p
align="justify">Delphi programcılarının uzun zamandır en çok yakındıkları ve Delphi derleyicisi tasarımcılarının başını ağrıttıkları belli başlı konular vardır. Birisi şüphesiz parametrize tiplerdir(generics, c++ için STL). Highlander sürümü ile birlikte bu özellik de Delphi&#8217;ye kazandırılmış olacak. Diğerleri de nested tipler, class static tipler ve operator overloading olarak sıralanabilir. Parametrize tipler hariç diğerlerini hem Delphi, hem de Delphi.NET için şu anda kullanabiliyoruz.</p><p
align="justify">Bu makalemizde göreceğimiz operator aşırı yükleme veya operator overloading, sınıf ya da record&#8217;ların kullanımını büyük bir ölçüde genişletmektedir.  Delph.NET için hem record hem de class veri tipleri için operator overloading yapılabilirken, Delphi for Win32 için sadece record veri tiplerinde operator overloading yapılabilir. Ama bu kullanım bakımından o kadar da etki etmemektedir. Hatta çoğu durumda operator overloading için record kullanılmaktadır. Vereceğimiz örnekler sınıflar ile yapılmış olduğundan Delphi.NET ortamında denemelisiniz. Sınıflar ile örnek veriyorum, çünkü recordlar&#8217;dan farklı olarak yapılacak fazladan bir kaç işlem var. Mesela record&#8217;larda çoğu durumda Result çıkış değeri Record olduğundan, Create ile oluşturmanıza gerek yok.</p><h1>Ayran&#8217;nın Suyu Fazla mı Olmuş, Ne?</h1><p
align="justify">Operator overloading&#8217;i anlatabilmek için böylesine uçuk sayılabilecek bir örnek seçtim. Belki ayran içtikçe bu konuyu hatırlarsınız <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p
align="justify">Şimdi 3 adet tipimiz olsun. TAyran, TYogurt ve TSu. TAyran sınıfı içinde hem TYogurt tipinde, hem de TSu tipinde iki adet özelliğimiz olsun. TTuz da olurdu ama şimdilik ayranımız tuzsuz olsun <img
src='http://www.diyezon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><pre>
<pre class="brush: delphi">TYogurt = class
  Miktar: Integer;
end;

TSu = class
  Miktar: Integer;
end;

TAyran = class
  Yogurt: TYogurt;
  Su: TSu;
public
  constructor Create;
end;

constructor TAyran.Create;
begin
  inherited;
  Yogurt := TYogurt.Create;
  Su := TSu.Create;
end;</pre></pre><p
align="justify">Şimdi diyelimki TAyran tipimize TYogurt ve TSu tiplerinde ekleme yapılabilsin. Ayrıca TYogurt ve TSu kendi aralarında toplanabilsin. Ayrıca bir de TAyran ile diğer tipler karşılaştırılmaya tabi tutulabilsin. Bu işlemleri siz, ayrı ayrı metodlar tanımlayarak ve bu metodları gerektiği yerde kullanarak gerçekleştirebilirisiniz. Ama operator overloading kullanarak aşağıdaki gibi işlemler yapabileceğiz:</p><pre>
<pre class="brush: delphi">var
  Yogurt: TYogurt;
  Su: TSu;
  Ayran: TAyran;
begin
  Yogurt := 15;
  Su := 5;
  Ayran := Yogurt + Su;
  Yogurt := Yogurt - 5;
  if Ayran &gt; Yogurt then
    ShowMessage(&#039;Ayrandaki yogurt miktarı daha fazla&#039;);
end;</pre></pre><p
align="justify">Nesne oluşturma kısımlarını konumuz dışında olduğu için atladım. Tabi ki bu işlemler, operator overloading olmadan hataya sebep olacaktır. &Ccedil;ünkü bir sınıf tipini kalkıp başka bir sınıf tipi ile topluyorsunuz, sonra bu sınıf tipine Integer ekliyorsunuz ve sonra da başka bir sınıf tipi ile karşılaştırmaya tabi tutuyorsunuz. Dediğim gibi bu işlemleri prosedür ve fonksiyonlarla da halledebilirsiniz. Ama bu işlemleri operator overloding üzerinden yaparsanız, kullanımda yukarıdaki gibi bir kolaylık sağlamış olacaksınız. Şimdi veri tiplerimiz ile yukarıdaki işlemleri gerçekleştirebilmek için gereken operator tanımlamalarını yapalım.</p><h1>Add ve Subtract</h1><p
align="justify">Şimdi TYogurt nesnesi için aşağıdaki tanımlamayı yapalım. Ama ondan önce TYogurt içinde TAyran ve TSu sınıflarına referanslarımız olduğundan ikisi için forward tanımlaması gerekmekte. &Ccedil;ünkü TAyran ve TSu, TYogurt&#8217;dan sonra tanımlanmıştır. Her neyse bu zaten nesne programlama konusu. Şu an bizim konumuzla alakası fazla yok.</p><pre>
<pre class="brush: delphi">
  TAyran = class; //forward tanımlama
  TSu = class; //forward tanımlama

  TYogurt = class
    Miktar: Integer;
    class operator Add(Yogurt: TYogurt; Su: TSu): TAyran; //Ayran := Yogurt + Su
    class operator Add(Yogurt1: TYogurt; Yogurt2: TYogurt): TYogurt; //Yogurt3 := Yogurt1 + Yogurt2
    class operator Subtract(Yogurt1: TYogurt; Yogurt2: TYogurt): TYogurt; //Yogurt3 := Yogurt1 - Yogurt2
  end;</pre></pre><p
align="justify">Gördüğünüz gibi üç adet satır ekledik. Bunlardan ilki &quot;+&quot; yani toplama operatorünün üzerine yazar. Bu class statik metod ile Add metodunun üzerine yazmak ile nesnemiz ile yapılacak olan her &quot;+&quot; toplama işleminde bu metod çağrılacaktır. Ama verdiğimiz kriterlere göre&#8230; Örneğimizde gördüğünüz gibi iki adet Add operatoru tanımlandı. Bunlardan ilki TYogurt ile TSu değerlerini topluyor ve sonucu TAyran olarak çıktı veriyor. İkincisi ise iki adet TYogurt nesnesin topluyor ve yine TYogurt cinsinden çıktı veriyor.</p><p
align="justify">Buradaki altın kural, eğer <strong>iki parametreli</strong> operator metodu var ise, tanımlayacağınız operator metodundaki parametrelerden <strong>en az birisi</strong> işleme girecek olan <strong>sınıftan</strong> olmalı. İki parametre alan çoğu operator metodları için bu mantık vardır. Bu yüzden bir operator&#8217;e overload yapacaksanız, kara kara hangi sınıfta tanımlıyacağınızı düşünmenize gerek yok. &Ccedil;ünkü işleme girecek olan herhangi bir sınıf bu metodun bir parametresi olacağından, işleme girecek olan herhangi bir sınıf içinde bu overload işlemini yapabilirsiniz. Mesela ilk Add tanımlamasını TSu sınıfında da yapabilirdik. &Ccedil;ünkü TSu da işleme girmektedir. Ama artık gerek kalmadı. &Ccedil;ünkü:</p><pre>
<pre class="brush: delphi">Ayran := Yogurt + Su;</pre></pre><p
align="justify">gibi bir ifade için bu Add metodu çağırılacaktır.</p><p
align="justify">Tek parametreli operator metodlarında ise aslında mantık ile parametresinin ne olacağını bilebiliyorsunuz. Zaten yanlış bir tanımlama yaptığınızda derleyici sizi uyaracaktır. Operator metodlarının parametreleri dahil tam listesi için yardım dosyasına müracaat etmelisiniz.</p><p
align="justify">En son satırdaki Subtract operator metodu ise &quot;-&quot; çıkarma işleminin görevini görmektedir. Burada gördüğünüz örnekte iki adet TYogurt nesnesi birbirinden çıkarılıp sonuç olarak TYogurt cinsinden çıktı veriliyor. Yani:</p><pre>
<pre class="brush: delphi">Yogurt3 := Yogurt1 - Yogurt2;</pre></pre><p>gibi.. Şimdi bu metodların kod kısımlarını da verelim.</p><pre>
<pre class="brush: delphi">class operator TYogurt.Add(Yogurt: TYogurt; Su: TSu): TAyran;
begin
  Result := TAyran.Create;
  Result.Yogurt.Miktar := Yogurt.Miktar;
  Result.Su.Miktar := Su.Miktar;
end;

class operator TYogurt.Add(Yogurt1, Yogurt2: TYogurt): TYogurt;
begin
  Result := TYogurt.Create;
  Result.Miktar := Yogurt1.Miktar + Yogurt2.Miktar;
end;

class operator TYogurt.Subtract(Yogurt1, Yogurt2: TYogurt): TYogurt;
begin
  Result := TYogurt.Create;
  Result.Miktar := Yogurt1.Miktar - Yogurt2.Miktar;
end;</pre></pre><p
align="justify">Gördüğünüz gibi Result değerlerini her defasında Create ile oluşturduk. &Ccedil;ünkü Result bir nesnedir. Ve Result ile atanacak olan nesne birbirinden farklıdır. İşte record kullanmanın bir yararı da burada. Create ile ikide bir oluşturmanıza gerek yok. Record kullanmanın tek dez avantajı, forward tanımlama yapamamanız. Ama bu sorun, her bir record&#8217;u ayrı dosyalara alınarak üstesinden gelinebilir. Ben bununla kafanızı karıştırmamak için sınıf&#8217;ları ve forward tanımlamaları kullandım. Ayrıa record&#8217;un bir avantajı da sınıf gibi private, public, protected alanlarda prosedür ve fonksiyon oluşturabilmenizdir. Gerçi bu özellik operator overloading ile aynı zamanda Delphi&#8217;ye kazandırılmıştır. Her neyse&#8230;</p><h1>Implicit ve Explicit</h1><p
align="justify">Şimdi diyelimki TYogurt tipindeki nesnemizi TAyran nesnesine dönüştüreceğiz. Yani TYogurt nesnesindeki miktarı, TAyran üzerine yazacaz. Bunun için TYogurt nesnesine şunu eklemeliyiz:</p><pre>
<pre class="brush: delphi">class operator Implicit(Yogurt: TYogurt): TAyran; //Ayran := Yogurt;</pre></pre><p
align="justify">Implicit operator metodu hangi sınıf veya record içinde tanımlanmış ise o sınıf veya record&#8217;u metodun Result kısmında bulunan sınıfa dönüştürür. Örneğimiz için bu Ayran değişkene Yogurt&#8217;u atamak ile olur. Bu metodun kodları ise örneğimize göre şöyle olabilir:</p><pre>
<pre class="brush: delphi">class operator TYogurt.Implicit(Yogurt: TYogurt): TAyran;
begin
  Result := TAyran.Create;
  Result.Yogurt.Miktar := Yogurt.Miktar;
end;</pre></pre><p
align="justify">Eğer sınıf için operator overloading kullanıyorsanız, burada ve diğer tanımlamalarda dikkat etmeniz gereken nokta parametre ile gelen nesneleri direk olarak Result içine atama yapmamanız. &Ccedil;ünkü bu taktirde sınıfın işaretçisini eşitlemiş olursunuz ve işler istemediğiniz noktalara gelebilir.</p><p
align="justify">Explicit operatorü ise <strong>mantık </strong>olarak aynıdır. Sadece kullanımda fark vardır. Yani yukarıdaki &quot;Ayran := Yogurt&quot; işleminde, kullanıcının böyle kolay bir şekilde eşitlemesini istemeyebiliriz. Yani direk böyle bir eşitleme yaptığında hata yapmış olabileceğini düşündürtmek için bu kullanıma izin vermeyebiliriz. Ve sadece type casting ile tip dönüşümüne izin verebiliriz. İşte bunu bize sağlayan operator Explicit&#8217;dir.</p><p
align="justify">&quot;Ayran := Yogurt&quot; eşitlemesini &quot;Ayran := TAyran(Yogurt)&quot; şeklinde yapabilmek için sadece yukarıda yazdığımız Implicit yazan yeri Explicit olarak değiştirin:</p><pre>
<pre class="brush: delphi">class operator TYogurt.Explicit(Yogurt: TYogurt): TAyran;
begin
  Result := TAyran.Create;
  Result.Yogurt.Miktar := Yogurt.Miktar;
end;</pre></pre><p
align="justify">Kod aynı kod, ama sadece Implicit yerine Explicit var. Bunu yapmakla artık &quot;Ayran := Yogurt&quot; çevirimi derleyici tarafından hatalı olarak görülecek ve &quot;Incompatible types&quot; yani uyumsuz tipler gibi bir hata verecektir. Böylece kullanıcıyı &quot;Ayran := TAyran(Yogurt)&quot; işlemini yapmaya zorlamış oluyoruz.</p><p
align="justify">Peki neden Implicit&#8217;i kaldırdık? Hem Implicit hem de Explicit operatorunu kullanamazmıydık. Kullanabiliridik. Ama Explicit çalışmazdı. &Ccedil;ünkü Implicit daima Explicit&#8217;den önceliklidir.</p><h1>Karşılaştırma</h1><p
align="justify"> Karşılaştırma işlemleri için bir çok operator vardır. Burada hepsine değinmemiz biraz zor. Sadece makalemizin başında verdiğimiz kodda kullandığımız &quot;&gt;&quot; büyüktür karşılaştırma operatoru için overload işlemini yapalım. Bu sefer dilerseniz TAyran sınıfımızda böyle bir tanımlama yapalım:</p><pre>
<pre class="brush: delphi">  TAyran = class
    Yogurt: TYogurt;
    Su: TSu;
  public
    constructor Create;
    class operator GreaterThan(Ayran: TAyran; Yogurt: TYogurt): Boolean;
  end;</pre></pre><p
align="justify">Karşılaştırma operatorlerini overload yaparken dönüş değerinin Boolean olmasına dikkat edin. Bu operator metodunu aşağıdaki gibi kodlayabiliriz:</p><pre>
<pre class="brush: delphi">class operator TAyran.GreaterThan(Ayran: TAyran; Yogurt: TYogurt): Boolean;
begin
  if Ayran.Yogurt.Miktar &gt; Yogurt.Miktar then
    Result := True
  else
    Result := False;
end;</pre></pre><p
align="justify">Yada daha kısa ve şık bir birçimde şöyle de olabilir:</p><pre>
<pre class="brush: delphi">class operator TAyran.GreaterThan(Ayran: TAyran; Yogurt: TYogurt): Boolean;
begin
  Result := Ayran.Yogurt.Miktar &gt; Yogurt.Miktar;
end;</pre></pre><p
align="justify">İçini nasıl doldurmanız gerektiği size kalmış. Ama burada Yogurt için de büyüktür operatorünü overload yapabilirdik. Bu durumda</p><pre>
<pre class="brush: delphi">Ayran.Yogurt.Miktar &gt; Yogurt.Miktar</pre></pre><p>yazmak yerine:</p><pre>
<pre class="brush: delphi">Ayran.Yogurt &gt; Yogurt</pre></pre><p
align="justify">yazabilirdik. Gerisi size kalmış.</p><h1>Sonuç</h1><p
align="justify">Burada değinmediğimiz bir çok operatöre aşırı yükleme yapabilirsiniz. Bunların tam listesi için yardım dosyasında &quot;Operator Overloading&quot; ile ilgili kısma bakmanız yeterli.</p><p
align="justify">Tabi burada verdiğimiz sınıflar için tek tek operator tanımlaması yaptığınızda ortalık biraz karışabiliyor. Bunların önüne geçmek için operator tanımlamalarını daha çok ata sınıflarda gerçekleştirmelisiniz. Böylece çocuk sınıflarda bu tanımlamaları bir daha yapmak zorunda kalmazsınız. Mesela örneğimizde TSu ve TYogurt sınıflarının her ikisinin de Miktar isminde bir özelliği mevcut. Bu iki sınıfı TSiviMadde gibi &quot;Miktar&quot; özelliği olan bir ata sınıftan türetebilirdiniz. Ve bu operator tanımlamalarını ata sınıf için yapıp, ayrı ayrı TSu ve TYogurt için yapmanıza gerek kalmazdı.</p><p
align="justify">Yorumlarınız önemlidir, bekliyorum.</p> ]]></content:encoded> <wfw:commentRss>http://www.diyezon.com/delphi-ve-operator-overloading/feed/</wfw:commentRss> <slash:comments>0</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.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/27 queries in 0.046 seconds using memcached
Object Caching 673/735 objects using memcached

Served from: www.diyezon.com @ 2012-02-08 12:01:50 -->
