Neden bu şekilde kod yazarız

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Neden bu şekilde kod yazarız

Mesaj gönderen kimimben »

Selamınaleyküm.

Uzun zamandır buna benzer kodları görüyorum sağda solda.
Aşağıda ki şekilde class'larımız olduğunu varsayalım.

Kod: Tümünü seç

TA = class
  procedure Test(); virtual; abstract;
end;

TB = class(TA)
  procedure Test(); override;
end;

TC = class(TA)
  procedure Test(); override;
end;
  
  
implementation

{$R *.dfm}

procedure TB.Test;
begin
  inherited;
  ShowMessage('B');
end;


procedure TC.Test;
begin
  inherited;
  ShowMessage('C');
end;

Kullanım :

Kod: Tümünü seç

procedure TForm2.FormCreate(Sender: TObject);
var
 A : TA;
begin
  A:= TB.Create();
  A.Test;
  A:= TC.Create();
  A.Test;
end;
Burada kafama takılan neden A değişkenini,TA tipinde tanımlıyoruz.
Aşağıda ki şekilde yazmak varken,neden yukarıda ki gibi yazıyoruz.

Kod: Tümünü seç

procedure TForm2.FormCreate(Sender: TObject);
var
 B : TB;
begin
  B:= TB.Create();
  B.Test;
end;
Neden bu şekilde kod yazarlar ki ? Saçma değil mi ?
Avantajı,dezavantajı var mı ?
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2356
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Neden bu şekilde kod yazarız

Mesaj gönderen freeman35 »

class konusunu tekrar gözden geçirmeni tavsiye ederim. Kim kimden türemiş vs. sen orda "test" e takılmışsın sanırım. Atadan gelenleri nasıl kullanırsın başka türlü ? oturup Ta da olanları Tb den kullanmak için ne yapman gerek ? en kısa şekilde.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Kullanıcı avatarı
badkursat
Üye
Mesajlar: 84
Kayıt: 03 Mar 2014 08:58

Re: Neden bu şekilde kod yazarız

Mesaj gönderen badkursat »

Eğer başka bir procedure veya function da değişkeninin ne olduğunu bilmiyorsan TA olarak tanımlamak mantıklı olabilir.

Ör:

Kod: Tümünü seç

procedure Example(AItem:TA);
begin
    if AItem is TB Then
       begin
       
       end
    else
       begin
      
      end;  
end;
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Neden bu şekilde kod yazarız

Mesaj gönderen kimimben »

freeman35 yazdı:class konusunu tekrar gözden geçirmeni tavsiye ederim. Kim kimden türemiş vs. sen orda "test" e takılmışsın sanırım. Atadan gelenleri nasıl kullanırsın başka türlü ? oturup Ta da olanları Tb den kullanmak için ne yapman gerek ? en kısa şekilde.
Biraz araştırma yaptığımda aşağıda ki kavramlara rastladım.

https://www.google.com.tr/#safe=off&q=d ... lymorphism
https://www.google.com.tr/#safe=off&q=d ... table+code
https://www.google.com.tr/#safe=off&q=d ... +mock+test

Ama bunlarla ne ilgisi olabilir ki ?
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

Bahsettiğiniz hususlar; nesneye yönelik programlamanın (OOP=Object Oriented Programming) anahtar elemanlarıdır ve bu metodolojiyi bilmemek ya da yeterince anlayamamak yeni nesil programlama dillerini yeterince iyi idrak edememek ve yeterli seviyede kullanamamak anlamına gelir. Bu neden ile; OOP öğrenmeye ağırlık vermelisiniz. Kavramları öğrenmeye başladıkça, programlama dillerinin benzer işlevselliği biraz farklı yollar ile sunduğunu da fark edeceksiniz. Inheritance, Encapsulation ve Polymorphism OOP'nin olmazsa olmazlarıdır. Tüm kavramları ve ne işe yaradıklarını hemen anlamaya çalışmayın, bir anda tam bir kavrayış pek mümkün değildir. Zamanla oturur bu anlayış ve oturduğunda ise hemen hemen herşeyi OOP olarak görmeye başlarsınız.

Bu bakış açısı size problem çözmede, kod tekrarlarını önlemede ve esneklikte inanılmaz kolaylıklar sağlar. OOP'ye aşina olup kullanmaya başladıkça büyük problemleri küçük parçalara bölmeye çalışacak ve problemlerin basitleştiğini gözlemleyeceksiniz.

Bu konuları Delphi ekseninde öğrenmek istiyor iseniz; Marco Cantu'nun Delphi 7 ve öncesi için yazılmış kitaplarından bir yada birden fazlasını okumanızı tavsiye edebilirim. Ancak, OOP öğrenmek için illa da bir dil'e bağımlı değilsiniz, OOP programlama dünyasında bir anlayış ve disiplin kalıbıdır. Bu disiplini öğrenmek için bir dile ihtiyaç duymazsınız ama elbette anladıklarınızı test edebilmek için bir dile ihtiyaç duyarsınız.

OOP'ye aşina olduğunuzda, C++, Java, Delphi, C# gibi dillerde benzer işlevselliğe sahip kodlar yazabilirsiniz. Tek fark syntax dediğimiz yazım farklılıklarıdır.

Polymorhism konusunda ise kendinize biraz daha zaman tanımanızda fayda vardır. Bu hususun kavranması diğerlerine oranla biraz daha zahmetli ve zaman alıcıdır. Kısaca bir örnek vereyim size:

Size şu şekilde bir soru gelse cevabınız ne olurdu ? "Elinize bir kağıt ve bir kalem alın ve kağıda bir şekil çizin"

Muhtemelen; "bir şekil çizeyim ama neyin şeklini çizeyim, üçgen mi, daire mi, kare mi, dikdörtgen mi ya da başka bir şey ?" diye soruya soru ile yanıt verirdiniz sanırım.

Programlama perspektifi ile bakıldığında elimizde Sekil isimli bir sınıfın olması gerektiğini ve bunun da bir Ciz metodu olması gerektiğini hayal edebilirsiniz bu bilgiler ışığında. Ancak sizin soruya soru ile yanıt verdiğiniz gibi, gariban bilgisayarda "şekil çiz" emrine nasıl yanıt vereceğini bilemeyecektir. Bu durumda, ilgili sınıf aşağıdaki gibi görünecektir.

Kod: Tümünü seç

  TSekil = class
  public
    procedure Ciz; virtual; abstract;
  end;
Neden virtual ? Çünkü bu sınıtfan türeyecek olan gerçek şekil sınıflarının Ciz metodunu özelleştirmeleri gerekecektir. Örneğin bir üçgen için Ciz metodunun içinde farklı kodlar bir kare için farklı kodlar olmalıdır. Peki neden abstract ? Çünkü, şekil sınıfının çiz metodunda neyi çizeceğimizi bilmiyoruz. Şekil çizelim çizmesine de neyin şeklini çizeceğiz ? Bu durumda, kalıtımdan istifade ederek aşağıdaki gibi bir şekil sınıfları hiyerarşisi oluşturabiliriz.

Kod: Tümünü seç

  TSekil = class
  public
    procedure Ciz; virtual; abstract;
  end;
  
  TUcgen = class(TSekil)
  public
    procedure Ciz; override;
  end;
  
  TKare = class(TSekil)
  public
    procedure Ciz; override;
  end;
  
  ..
  ..
  ..
  
procedure TUcgen.Ciz;
begin
  // Burada bir üçgen çizme kodu yazacaksınız
end;

procedure TKare.Ciz;
begin
  // Burada bir kare çizme kodu yazacaksınız
end;
 
Yukarıdaki hiyerarşiye bakarak ne gözlemliyorsunuz ? TUcgen ve TKare sınıflarının TSekil sınıfından miras alındığını(inheritance) görüyor olmalısınız. Bu durumda şöyle denilebilir; üçgen ve kare birer şekildir.! O halde şu şekilde bir kod yazar isek ne olur ?

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender : TObject);
var
  Sekil : TSekil;
begin
  Sekil := TKare.Create;
  try
    Sekil.Ciz;
  finally
    Sekil.Free;
  end;
end;
Yukarıdaki örnek polymorhism(çok şekillilik)'e bir örnek teşkil eder. Madem üçgen ve kare birer şekildir o halde ben şekil türündeki bir değişken ile kendilerini temsil edebilirim.

Bu kısa örnekler umarım kafanızda bazı şeylerin şekillenmesine imkan vermiştir. Bundan sonrası sizin araştırma ve öğrenme azminize aynı zamanda bol bol test yapmanıza bakıyor olacak.

Başarılar...
En son thelvaci tarafından 29 Oca 2016 10:12 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2356
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: Neden bu şekilde kod yazarız

Mesaj gönderen freeman35 »

Tuğrul bey herzaman dediğimi birkez daha sizde ispatlamışsınız. Öğretmek, anlatmak başlı başına bir meziyettir. Son noktaya kadar bende okudum, teşekkürler.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

Beğenmenize memnun oldum. Faydalı olabildi isek ne âla.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Neden bu şekilde kod yazarız

Mesaj gönderen kimimben »

Öncelikle soruma vakit ayırıp detaylı cevabınız için teşekkür ederim. Tuğrul Bey.

Sizin verdiğiniz örnekte de;

Kod: Tümünü seç

var
  Sekil : TSekil;
begin
 Sekil := TKare.Create;
Şeklinde bir kullanım söz konusu.Sekil değişkeni TSekil tipinde tanımlanmış,
Halbu ki ;

Kod: Tümünü seç

var
Sekil : TKare;  
Şeklinde tanımlasak kod yine derlenecekti değil mi ? (Evet)
Ama bu sefer de TKare veya TUcgen tiplerine bağımlı bir kod yazmış olacaktık.

Ama değişkeni soyut olarak(soyuttan kastım abstract bir sınıf veya interface) olarak tanımlıyoruz ki,yeni implementasyonlar ekleyebilelim,kodu değiştirmesi,test etmesi kolay olsun.

Yani şöyle ;

Kod: Tümünü seç

 ISekil = Interface(IInterface)
    procedure Ciz;
  end;

  TKare = class(TInterfacedObject, ISekil)
  public
    procedure Ciz;
  end;

  TUcgen = class(TInterfacedObject, ISekil)
  public
    procedure Ciz;
  end;
  
implementation
{$R *.dfm}
 
  { TKare }
 procedure TKare.Ciz;
 begin
  // to do
 end;

 { TUcgen }
 procedure TUcgen.Ciz;
 begin
  // to do
 end;
  
Kullanıma gelince ;

Kod: Tümünü seç

procedure TForm1.FormCreate(Sender: TObject);
var
 Sekil : ISekil;
begin
 Sekil := TKare.Create;
 Sekil.Ciz;   
end;
Yarın bizden sisteme kare,üçgen dışında örneğin dikdörtgen çizen işlevi yerine getirmesi istenirse,tek yapmamız gereken aşağıda ki gibi adaptasyon olmalı.

Kod: Tümünü seç

  TDikdortgen = class(TInterfacedObject, ISekil)
  public
    procedure Ciz;
  end;

 procedure TForm1.FormCreate(Sender: TObject);
 var
  Sekil : ISekil;
 begin
  Sekil := TDikdortgen.Create;
  Sekil.Ciz;   
 end;
Bu şekilde bir kod yazdığımızda ,nesne tabanlı tasarım prensiblerinden SOLID (object-oriented design),
OCP yani "Open/closed principle" yani "yazdığımız kodlar geliştirmeye açık,değişime kapalı prensibini" mi uygulamış oluyoruz sanki.

Sanki poliformik yapıların olduğu bir tasarımda yazılıma yeni özellikler eklemek,mevcut kodu değiştirmek,kodun test edilebilirliğini artırmak daha kolay gibi.
En son kimimben tarafından 02 Şub 2016 09:33 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

Soruyu açan ile son yanıtı veren arkadaşımız aynı arkadaşımız ise ilk sorusu ve son cevabı arasında evrim geçirmiş bir farklılık hissediliyor. Bu kıymetli bir şey elbette. Polymorphic kodlamanın avantajlarını anlayabildi iseniz ve bunu da uygulamalarınızda kullanıyor iseniz o halde sorunuzun nedenini anlayamadım açıkçası. Son verdiğiniz örnekler interface'ler üzerinden. Bu hususla alakalı bir makalem var sitemde vaktiniz olur ise okuyabilirsiniz, belki faydalı hususlar bulabilirsiniz.

OOP'de polymorphism(çok şekllilik)'in kullanılmasının zaruret olduğu pek çok durum da vardır. Yine bir örnek senaryo üzerinden ilerlemeye çalışalım:

Sizin bir yazılım ekibinin lideri olduğunuzu varsayalım ve bu ekipten birden fazla veritabanına destek vermeleri gereken bir bileşen seti üretmelerinin istendiğini düşünelim(UniDAC, SDAC vb.). Bu durumda, her bir veritabanı bileşenini bir alt gruba verdiğinizi düşünelim. TSQLConnection'ı bir gruba; TOracleConnection'ı bir gruba ve TSybaseConnection'ı da bir diğer gruba vermiş olalım. İşin doğası gereği, programcıları belirli bir disiplin altında tutmanız gerekir; aksi taktirde bir grup connection açmak için Open adlı bir metod yazabilecekken bir diğeri Connect isimli bir metod yazabilir; bir diğer grup ise Connected isimli bir property yazabilir. Bu durumda ürün istikrarsız bir yapıya bürünür.

Örneğin:

Kod: Tümünü seç

  TCustomConnection = class // Bu sınıfın implementasyonuna daha sonra değineceğiz.
  
  TSQLConnection = class(TCustomConnection)
  public
    procedure Open;
    procedure Close;
  end;
  
  TOracleConnection = class(TCustomConnection)
  public
    procedure Connect;
    procedure Disconnect;
  end;
  
  TSybaseConnection = class(TCustomConnection)
  private
    fConnected : Boolean;
    
    function GetConnected : Boolean;
    procedure SetConnected(const Value : Boolean);
  public
    property Connected : Boolean read GetConnected write SetConnected;
  end;
gibi bir yapı kurulmuş olabilir. Tek tek sınıf bazında bakıldığında bu elbette bir problem çıkartmaz. Ancak! Ya sizin ürününüzü kullanacak olan bir başka yazılım geliştirici; aynı anda runtime sırasında belirli koşullara göre birden fazla veritabanına destek vermesi gerekiyor ise nasıl bir kodlama yapacak ?

Örneğin;

Kod: Tümünü seç

var
  AConnection : TCustomConnection;
begin
  case ConnectionRadioGroup.ItemIndex of
    0 : AConnection := TSQLConnection.Create;
    1 : AConnection := TOracleConnection.Create;
    2 : AConnection := TSybaseConnection.Create;
  end;
  
  AConnection. ?? // Burada Open'mı, Connect'mi yoksa Connected := true kodu mu çağrılacak ?
end;
Yukarıdaki basit örnekten gözlemleyeceğiniz üzere ürününüzü kullanacak olan yazılımcı hangi metodu çağıracağını bilemeyecektir. Bu bir tasarım hatasıdır. TCustomConnection'da Open ve Close isimli metodlarınızı tanımlayıp alt ekiplerinize bu metodları ezmelerini söyleyebilir ve problemi çözebilirsiniz. Ya da IConnection isminde bir interface'i implemente etmelerini dolayısı ile ilgili metodların alt sınıflarda kesinlikle tanımlanmış olmasını garanti etmelerini de istemiş olabilirsiniz.

Başta da söylediğim gibi bu bir disiplin meselesi. Polymorhism ise ata sınıf türünde tanımlanmış olan bir değişkenin istenilen herhangi bir alt sınıf olarak oluşturulmasını sağladığımız küçük örneğimizde devreye giriyor. Bu sayede, ata sınıfta tanımlı olan virtual metodları çağırdığınızda aslında ata sınıfın metodunu değil alt sınıfın metodlarını çağırmış olursunuz. static metod çağrımlarında ise bu iş böyle değildir elbette.

Bu sayede aşağıdaki gibi garip bir kullanıma ihtiyacınız kalmaz:

Kod: Tümünü seç

var
  ASQLConnection : TSQLConnection;
  AOracleConnection : TOracleConnection;
  ASybaseConnection : TSybaseConnection;
begin
  ASQLConnection := nil;
  AOracleConnection := nil;
  ASybaseConnection := nil;

  case ConnectionRadioGroup.ItemIndex of
    0 : ASQLConnection := TSQLConnection.Create;
    1 : AOracleConnection := TOracleConnection.Create;
    2 : ASybaseConnection := TSybaseConnection.Create;
  end;
  
  if ConnectionRadioGroup.ItemIndex = 0 then
    ASQLConnection.Open;

  if ConnectionRadioGroup.ItemIndex = 1 then
    AOracleConnection.Open;
  
  if ConnectionRadioGroup.ItemIndex = 2 then
    ASybaseConnection.Open;

...
...
end;

Dediğim gibi bu hususlar en güzel kendiniz denediğiniz de anlaşılır hâle gelecektir.

Kolay gelsin
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Neden bu şekilde kod yazarız

Mesaj gönderen kimimben »

freeman35 yazdı:bütün yazıyı tekrar alıntı yapman gereksiz
Soruyu soran ve cevap veren aynı arkadaş :D

Genel de birşeyleri öğrenip,anlamaya çalışırken tek bir kaynak ya da görüşe bağlı kalmadan o konuyla ilgili tüm kaynakları incelemeye ve aralarında ki kullanım farklarını avantaj dezavantajlarını düşünmeye çalışırım.

Ayrıca verdiğiniz veritabanı senaryosu için teşekkür ederim.Bu konuda biraz daha araştırma yaptığımda aşağıda ki örneğe rastladım.Sanırım java kodu.
https://refactoring.guru/replace-condit ... lymorphism
Anladığım kadarı ile şartlı ifadeleri(if,switch,case of vs),poliformizm ile değiştirmemizi söylüyor.

Sanırım sizin de daha önce "Bu sayede aşağıda ki gibi garip bir kullanıma ihtiyacınız kalmaz" dan kastettiğiniz gibi,poliformik bir yapıda,if ve case of gibi şartlı ifadeleri ortadan kaldırırak "daha sadece" ve "daha esnek" bir kodlama elde etmiş oluyoruz.Peki...

Böyle bir senaryo olmaz belki ama örnek teşkil etmesi açısından ;
Bir TComboBox nesnesinde üç tane eleman olduğunu düşünürsek eğer;
"SQL Connection"
"Oracle Connection"
"SysBase Connection"
Ve yine bu seçimlere göre ilgili bağlantıyı,ilgili sınıf yardımı ile açmak(Open;) yada kapatmak(Close;) istersek yine,
if veya case of yazmak durumunda kalacağız gibi görünüyor.
Poliformik bir yapıda kodlamış da olsak, "Bu sayede aşağıda ki gibi garip bir kullanıma ihtiyacınız kalmaz" ,cümlesinde geçtiği gibi o garip kullanıma yine dönmüş olacağız sanki.
Yani şöyle olduğunu varsayalım;

Kod: Tümünü seç

procedure TForm1.ComboBox1Change(Sender: TObject);
var
 AConnection : TCustomConnection;
begin
  case ComboBox1.ItemIndex of
    0 : AConnection := TSQLConnection.Create;
    1 : AConnection := TOracleConnection.Create;
    2 : AConnection := TSybaseConnection.Create;
  end;
  AConnection.Open();
end;

Sanırım şu şekilde bir ilave daha yapsak,if ve case of lardan kurtulmuş olacağız;

Kod: Tümünü seç

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Generics.Collections,
  Vcl.StdCtrls;

type

  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TCustomConnection = class
    procedure Open; virtual; abstract;
    procedure Close; virtual; abstract;
  end;

  TSQLConnection = class(TCustomConnection)
  public
    procedure Open; override;
    procedure Close; override;
  end;

  TOracleConnection = class(TCustomConnection)
  public
    procedure Open; override;
    procedure Close; override;
  end;

  TSybaseConnection = class(TCustomConnection)
  public
    procedure Open; override;
    procedure Close; override;
  end;

var
  Form1: TForm1;
  AMap: TDictionary<Integer, TCustomConnection>;

implementation

{$R *.dfm}

{ TSQLConnection }
procedure TSQLConnection.Close;
begin
  OutputDebugString('SQL connection closed.');
end;

procedure TSQLConnection.Open;
begin
  OutputDebugString('SQL connection opened.');
end;

{ TOracleConnection }
procedure TOracleConnection.Close;
begin
  OutputDebugString('Oracle connection closed.');
end;

procedure TOracleConnection.Open;
begin
  OutputDebugString('Oracle connection opened.');
end;

{ TSybaseConnection }
procedure TSybaseConnection.Close;
begin
  OutputDebugString('Sybase connection closed.');
end;

procedure TSybaseConnection.Open;
begin
  OutputDebugString('Sybase connection closed.');
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  ACustomConnection: TCustomConnection;
  AConnectionMap: TDictionary<Integer, TCustomConnection>;
begin
  ComboBox1.Items.Add('SQL Connection');
  ComboBox1.Items.Add('Oracle Connection');
  ComboBox1.Items.Add('Sybase Connection');
  ComboBox1.ItemIndex := 1;

  AConnectionMap := TDictionary<Integer, TCustomConnection>.Create();
  AConnectionMap.Add(0, TSQLConnection.Create);
  AConnectionMap.Add(1, TOracleConnection.Create);
  AConnectionMap.Add(2, TSybaseConnection.Create);

  AConnectionMap.TryGetValue(ComboBox1.ItemIndex, ACustomConnection);
  ACustomConnection.Open;
end;

end.
Örnek teşkil etmesi açısından,böyle bir kodlama yaptım.Aksi takdirde TDictionary'ye "nesne örneklerini"(instance) eklemek yerine,sınıfların meta bilgilerini ekledikten sonra,ihtiyaç duyulan ilgili sınıfın,meta bilgilerinden oluşturarak yazmak daha akıl karı bir kodlama olacaktır diye düşünüyorum.Çünkü her veritabanı için, ilgili veritabanı sınıfı implementasyonu yazılmış, hali hazırda olabilir.Ama,belki de veritabanı sınıfı hiç kullanılmayarak gereksiz yere bellekte yer işgal edecektir diye düşünüyorum.

Bu konularda ki fikir ve önerilerinizi paylaşırsanız sevinirim.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

Madem bu hususlarda araştırmayı seviyorsunuz; o halde Delphi ekseninde işin özü olanı da araştırmanızı salık verebilirim. Virtual Method Table(VMT), Dynamic Method Table(DMT) ve Interface Method Table(IMT) nedir ;)

Bu bilgiler, bakış açınızı zenginleştirecek.
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen SimaWB »

Ya bu adam Cennetlik yaaa !!! :bravo:
Gönül istiyor ki; Tuğrul Bey çalışmasın, sadece bu forumun yada kendi web sitesinin yazarı olsun. O yazsın biz okuyalım... (Tabi sonra ar-ge :wink: )
There's no place like 127.0.0.1
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

SimaWB yazdı:Ya bu adam Cennetlik yaaa !!! :bravo:
Gönül istiyor ki; Tuğrul Bey çalışmasın, sadece bu forumun yada kendi web sitesinin yazarı olsun. O yazsın biz okuyalım... (Tabi sonra ar-ge :wink: )
Allah cümlemizi cenneti ile şereflendirsin.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Neden bu şekilde kod yazarız

Mesaj gönderen kimimben »

Tuğrul bey önerilerinizi dikkate alarak yaptığım araştırmalar sonucunda kafamda şunlar oluştu.
Ne kadar doğru,ne kadar yanlış anladım bilmiyorum ama,anladıklarımı burada paylaşırsam belki eğer yanlış anlamışsam,düzeltme imkanı bulurum.

Virtual method table(VMT) sayfasında belirtildiği üzere başka bir ifade şekli ile "Run-time method binding" yani çalışma zamanında method bağlama,değiştirme gibi bir anlam içeriyor.

Derleyici virtual method tanımlı bir sınıf gördüğünde,bu sınıf içersine gizli bir array yerleştirip,bu array içersinde de methodların adreslerini(pointer) tuttuğunu,ve çalışma zamanında da bu adreslere(pointer) ilgili,çağrılacak methodları set ettiğini söylediğini anlıyorum.

Yani aslında poliformizmin özeti aslında "At runtime these pointers will be set to point to the right function" belirtildiği gibi,class içersinde tutulan pointer listesini ilgili fonksiyonlara yönlendirmek ?

Bu şekilde düşündüğümüzde tüm bu OOP özellikleri(virtual method,interface vs) aslında,yazılımcılar için bir Encapsulation görevi görüyor.
Yani biz OOP programlama özelliklerini kullanarak,hangi pointerı hangi fonksiyonun pointerına bağlayacaktık diye kafa yormuyoruz.

Eğer sınıf,interface,virtual method diye birşey olmasaydı o zaman;

Delphi

Kod: Tümünü seç

types
TOpenDb = procedure;

procedure OpenOracle();
begin
  OutputDebugString('Oracle connection opened.');
end;

procedure OpenMsSQL();
begin
  OutputDebugString('MSSQL connection opened.');
end;

procedure OpenSysbase();
begin
  OutputDebugString('Sysbase connection opened.');
end;

var
 OpenDb : TOpenDb;
begin
 OpenDb := OpenOracle;
 OpenDb := OpenMsSQL;
 OpenDb := OpenSysbase;
 OpenDb();
end;
C++

Kod: Tümünü seç

void (*OpenDb)();

void OpenOracle()
{
  OutputDebugString(L"Oracle connection opened.");
}

void OpenMsSQL()
{
  OutputDebugString(L"MSSQL connection opened.");
}

void OpenSysbase()
{
 OutputDebugString(L"Sysbase connection opened.");
}

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
  OpenDb = OpenOracle;
  OpenDb = OpenMsSQL;
  OpenDb = OpenSysbase;
  OpenDb();
}
Sanırım böyle bir kodlama yapıyor olacaktık ? :D
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Neden bu şekilde kod yazarız

Mesaj gönderen thelvaci »

Bravo, basitleştirilmiş şekli ile aynen öyle. Derleyicinin bizim için oluşturduğu method pointer'larından başka bir şey değil aslında. Buradan ise genel anlamı ile pointer'lar ve VMT hakkında güzel malümatlar elde edebilirsiniz.
Cevapla