Ana içeriğe atla

Asım'ın ders notları - I

Lanet olsun sana ey zalim nesne, Beni değirmende taşa döndürdün Kendi kendine ne mırıldanıp duruyon Asım ? Gel yanıma sana bişeler gösterecem. Geliyom abi... ..... ..... Şimdi yapacağım şey bazı veritabanı işlemleri için kendi nesnemi oluşturup işlemleri bu nesneye yıkmak, Asım. Ben nesneye sadece "şu hesaptan şu hesaba şu miktarı havale yap" diye emir verip işlemin nesne tarafından yapılmasını sağlayacam. Abi "Zengin yedek kulubesi" ne ne oldu ? Ona biraz ara verdik ilerde tekrar dönecez Asım. Sen şimdi buraya konserve ol bakim. İlk önce her hangi bir veritabanında CARI adında bir tablo oluşturalım ve bu tabloya aşağıdakilere uygun bir şekilde alanları ekleyelim. Ben firebird kullandım, tablonun ddl ise aşağıda gözüken şekilde. Tabi burda gözükmeyen trigger, generator gibi bazı kodlar da var ama onlar şimdilik konumuz değil.
CREATE TABLE CARI (
    ID      INTEGER NOT NULL,
    AD      VARCHAR(20) COLLATE PXW_TURK,
    SOYAD   VARCHAR(20) COLLATE PXW_TURK,
    BAKIYE  NUMERIC(15,2)
);
Tabloyu oluşturduktan sonra programın grafik arayüzünü ve veritabanına bağlantı için gerekli olan bileşenlerimizi ayarlıyoruz. Firebird'e bağlanmak için ben IBX bileşenlerini kullandım. Yapmak istediğimiz iş Havale yapmak. Bunun için bize gerekenler bir adet havale yapacak insan, bir adet havale yapılacak insan ve yapılacak olan havale miktarı. Hepsi bu. Kullanıcıya bu değerleri girebilmesi/seçebilmesi için ekranda iki adet TDBLookupComboBox ve bir adet TEdit bulunuyor. DBLookupComboBox1 havale yapacak kişiyi belirtmekle birlikte dfm dosyasındaki kaydı :
  object DBLookupComboBox1: TDBLookupComboBox
    Left = 136
    Top = 18
    Width = 225
    Height = 21
    KeyField = 'ID'
    ListField = 'AD;SOYAD'
    ListSource = DataSource1
    TabOrder = 1
  end
DBLookupComboBox2 havale yapılacak kişiyi belirtmekle birlikte dfm dosyasındaki kaydı :
  object DBLookupComboBox2: TDBLookupComboBox
    Left = 136
    Top = 48
    Width = 225
    Height = 21
    KeyField = 'ID'
    ListField = 'AD;SOYAD'
    ListSource = DataSource1
    TabOrder = 2
  end
Veritabanı ayarlarına girmiyorum. Sen bunları zaten biliyon Asım. Şimdi bize bu işi yapacak bir nesne gerekiyor. Aklıma ilk gelen nesne arayüzü aşağıdaki gibi oldu.
HavaleNesnesi.HavaleYapacakKisi -özellik-
HavaleNesnesi.HavaleYapilacakKisi -özellik-
HavaleNesnesi.HavaleMiktari -özellik-
HavaleNesnesi.HavaleIsleminiYap -metod-
O zaman Nesnemizi yapmaya başlayalım. Yeni bir Unit oluşturup UnitHavale adında kaydettim. Daha sonra aşağıdaki gibi nesneyi oluşturdum.
type
  THavale = class
  private
    fHavaleYapanCariID   :Integer;
    fHavaleYapilanCariID :Integer;
    fHavaleYapilanMiktar :Double;
    function  GetHavaleYapanCariID: Integer;
    procedure SetHavaleYapanCariID(const Value: Integer);
    function  GetHavaleYapilanCariID: Integer;
    procedure SetHavaleYapilanCariID(const Value: Integer);
    function  GetHavaleYapilanMiktar: Double;
    procedure SetHavaleYapilanMiktar(const Value: Double);

  public
  Procedure HavaleYap;
  property  HavaleYapanCariID   : Integer 
read GetHavaleYapanCariID write SetHavaleYapanCariID;
  property  HavaleYapilanCariID : Integer 
read GetHavaleYapilanCariID write SetHavaleYapilanCariID;
  property  HavaleYapilanMiktar : Double  
read GetHavaleYapilanMiktar write SetHavaleYapilanMiktar;
  end;
//
//
HavaleYap proseduru hariç diğer fonksiyon ve prosedurler sadece private veriye ulaşmaya ve değerini set etmeye yaradığından sadece birini yazmam yeterli.

function THavale.GetHavaleYapanCariID: Integer;
begin
    Result := fHavaleYapanCariID;
end;

procedure THavale.SetHavaleYapanCariID
(const Value: Integer);
begin
  fHavaleYapanCariID := Value;
end;
//
//
İşlemleri tamamladığımıza göre sıra HavaleYap metodunu yazmaya geldi. Lan Asım ! Bu metodda nesnenin hangi veritabanına bilgi ekleyeceği eksik. Niye uyar mıyon? Bunun için nesneye Veritabanı adında TIBDatabase tipinde değer alan bir özellik ekledim.
property  Veritabani          : TIBDatabase  
read GetVeritabani write SetVeritabani;
Şimdi HavaleYap metodunu yazabiliriz.

procedure THavale.HavaleYap;
begin

 IBSqlOlustur;

 if fibsql.Transaction.InTransaction = False Then
    fibsql.Transaction.StartTransaction;
try
 try

   fibsql.Close;
   fibsql.SQL.Clear;
   fibsql.SQL.Add('Update CARI set BAKIYE = BAKIYE + ' +
 FloatToStr(HavaleYapilanMiktar));
   fibsql.SQL.Add('Where ID =' + 
IntToStr(HavaleYapilanCariID));
   fibsql.ExecQuery;


   fibsql.Close;
   fibsql.SQL.Clear;
   fibsql.SQL.Add('Update CARI set BAKIYE = BAKIYE - ' + 
FloatToStr(HavaleYapilanMiktar));
   fibsql.SQL.Add('Where ID =' + 
IntToStr(HavaleYapanCariID));
   fibsql.ExecQuery;

   fibsql.Transaction.CommitRetaining;

 except
   fibsql.Transaction.RollbackRetaining;
   Raise Exception.Create
   ('Dikkat!!! Havale işlemi başarılı olamadı...');
 end;

finally
 IBSqlYokEt;
end;

end;



procedure THavale.IBSqlOlustur;
begin

 if not Assigned(fIBDatabase) Then
   Raise Exception.Create
  ('Bağlanılacak Veritabanı bulunamadı. İşlem iptal ediliyor !!!');

  if Assigned(fibsql) Then Exit;

  fIbSql := TIBSQL.Create(nil);
  fIbSql.Database := Veritabani;
  fIbSql.Transaction := Veritabani.DefaultTransaction;
end;

procedure THavale.IBSqlYokEt;
begin
   FreeAndNil(fibsql);
end;
//
//
Şimdi işlemi gerçekleştirecek olan düğmenin click olayına ilgili kodumuzu yazalım.
procedure TForm1.btnHavaleYapClick(Sender: TObject);
var
Havale :THavale;
begin

Havale :=THavale.Create;
try
 Havale.Veritabani :=IBDatabase1;
 Havale.HavaleYapanCariID :=DBLookupComboBox1.KeyValue;
 Havale.HavaleYapilanCariID :=DBLookupComboBox2.KeyValue;
 Havale.HavaleYapilanMiktar :=StrToFloat(edit1.Text);
 Havale.HavaleYap;
 ShowMessage('Havale Başarılı');
finally
 FreeAndNil(Havale);
end;

end;
//
//
Programı çalıştırıyoruz ve listelerden uygun kişileri seçip havale miktarını da yazdıktan sonra Havale Yap düğmesine tıkladığımız zaman havale işlemini yapıyoruz. Ardından veritabanına gözatarak işlemin doğru olup olmadığını kontrol ediyoruz. Gayet başarılı :) Asım: Sistem iyi güzel çalışıyo da biz neden böyle bir şey yaptık. Havale Yap butonuna aşağıdaki kodları yazsak bizim işimizi görmez mi ? Neden THavale adında bi nesne tanımlayıp 170 - 20 = 150 satır daha fazladan kod yazdık ? Ne kadar kod, o kadar kafa karışıklığı demek değil mi?
procedure TForm1.btnHavaleYapClick(Sender: TObject);
begin
 try
   IBSQL1.Close;
   IBSQL1.SQL.Clear;
   IBSQL1.SQL.Add('Update CARI set BAKIYE = BAKIYE +
 ' + edit1.Text);
   IBSQL1.SQL.Add('Where ID =' +
 IntToStr(DBLookupComboBox1.KeyValue));
   IBSQL1.ExecQuery;


   IBSQL1.Close;
   IBSQL1.SQL.Clear;
   IBSQL1.SQL.Add('Update CARI set BAKIYE = BAKIYE - ' + 
Edit1.Text);
   IBSQL1.SQL.Add('Where ID =' + 
IntToStr(DBLookupComboBox2.KeyValue));
   IBSQL1.ExecQuery;

   IBSQL1.Transaction.CommitRetaining;

 except
   IBSQL1.Transaction.RollbackRetaining;
   Raise Exception.Create
('Dikkat!!! Havale işlemi başarılı olamadı...');
 end;

end;
//
//
Asım, böyle yazacaksın. Nesneye dayalı yazılım diyosan al sana nesne işte. Bu kodu butona yazacan da ne olacak ? İki gün sonra başka bi formdan tekrar havale yapmak istersen ne olacak? Burdaki kodu alıp oraya mı yapıştıracan ? Hadi sen neysende senden sonra bu programın gelişimini devam ettirecek çaylağın BAKIYE = BAKIYE * MIKTAR gibi bi kod yazmayacağını garanti edebilir misin? Böyle ulu orta yere serpilmiş bir kodla Teste dayalı yazılım nasıl geliştireceksin ayıptır sölemesi ? Birçok yerden havale yaptığın vakit, havale işleminde meydana gelecek bi değişikliği programa nasıl yansıtacan ? Butonlara yazdığın iki kodu şöyle bir karşılaştırdığında hangisi daha anlaşılır, hataya yapma olasılığı daha az ve kolay okunabilir ? Aldırma elime karamiş sopasını Asım ! :) Devam ediyoruz... Günün birinde yetkili amcam geldi ve "Sistemde açık var. Bakiyesinde yeterli miktarda parası olmayan kişi havale yapabiliyor?. Bu nasıl bir iş ? Sen nasıl bir programcısın?" diye bize fırçayı attı. Altında kalma. Ver cevabını. (Bu senin işten atılmana engel olmuyorsa tabi) "Ne kızıyon yaw ? Yaparız iki dakka da" dedin ve işe koyuldun. Nesnemizin bulunduğu uniti açıp değişiklik yapcaz. Hepsi bu. Sonra programı yeniden derleyecez. Sonra programı bankadaki tüm memurların bilgisayarına yeniden yükleyecez. (mi acaba ? Nesneye dayalı yazılım, dağıtık uygulamalarda da çok önemli Asım) Nesnemizin Private alanına Function HavaleYapacakKisininYeterliBakiyesiVarmi:Boolean; adlı bi fonksiyon ekledik. Bu fonksiyonun nesnemizi kullanan kişiler tarafından görünmesini istemiyoruz çünkü. Bu da nesnenin gövdesi :
function 
THavale.HavaleYapacakKisininYeterliBakiyesiVarmi: Boolean;
begin
fIbQuery :=  TIBQuery.Create(nil);
try
  Result := False;
  fIbQuery.Database    := fIbSql.Database;
  fIbQuery.Transaction := fIbSql.Transaction;
  fIbQuery.Close;
  fIbQuery.SQL.Clear;
  fIbQuery.SQL.Add('Select BAKIYE FROM CARI WHERE ID =' + 
IntToStr(HavaleYapanCariID));
  fIbQuery.Open;
  Result := fIbQuery.Fields[0].AsFloat - 
HavaleYapilanMiktar >= 0.00;
finally
 FreeAndNil(fIbQuery);
end;

end;
//
//
Sonra havale yap prosedurune bunu ekliyoruz.
procedure THavale.HavaleYap;
begin

 IBSqlOlustur;

 if HavaleYapacakKisininYeterliBakiyesiVarmi = False Then
   Raise Exception.Create
('İşlem yapacak kişinin bakiyesi yeterli değil. İşlem iptal ediliyor !!!');

 if fibsql.Transaction.InTransaction = False Then
    fibsql.Transaction.StartTransaction;
...
...
//
//
İşimiz bitti... Müdür : - Hişt aloooo! Napıyonuz lan orda siz ikiniz ? Yine ogame ' mi oynuyonuz ? Asım : - Yok patron ! Sadece grafiklerini inceliyoduk. Müdür : - Yaw benim biraz metale ihtiyacım var. Bi nakliye çıkartsanız bana. He ! Asım : - Valla olsa dükkan senin müdür bey. Müdür : - Neyse ben buraya size bişe sölemek için geldim. Bundan sonra Havale yapan kişiden havale ücretinin % 1'i kesilecek. Hadi bir an önce yapın şunu. Asım : (Yaw tam da filoyu saldırıya göndermiştim. hay allah) - Tamam müdür bey.
...
...

  private
    fHavaleYapanCariID   :Integer;
    fHavaleYapilanCariID :Integer;
    fHavaleYapilanMiktar :Double;
    fIBDatabase :TIBDatabase;
    fIbSql : TIBSQL;
    fHavaleUcreti : Double; // yeni eklenen satır
...
...




HavaleYap Proseduru
...
...

   fHavaleUcreti := HavaleYapilanMiktar / 100;

   fibsql.Close;
   fibsql.SQL.Clear;
   fibsql.SQL.Add('Update CARI set BAKIYE = BAKIYE - '+
 FloatToStr(HavaleYapilanMiktar + 
 fHavaleUcreti));
   fibsql.SQL.Add('Where ID =' + 
IntToStr(HavaleYapanCariID));
   fibsql.ExecQuery;
...
...
...
//
İşlem tamam abi.

Yorumlar

Sadettin POLAT dedi ki…
Asım, seni bi deneyeyim dedim sen de yuttun yani. Ben sana kaç kere parametreleri kullan demedim mi? He !!


fibsql.Close;
fibsql.SQL.Clear;
fibsql.SQL.Add('Update CARI set BAKIYE = BAKIYE + :P_BAKIYE' );
fibsql.SQL.Add('Where ID = :P_CARIID');
fibsql.Params[0].AsFloat := HavaleYapilanMiktar;
fibsql.Params[1].AsInteger := HavaleYapilanCariID;
fibsql.ExecQuery;

fHavaleUcreti := HavaleYapilanMiktar / 100;
fibsql.Close;
fibsql.SQL.Clear;
fibsql.SQL.Add('Update CARI set BAKIYE = BAKIYE - :P_BAKIYE');
fibsql.SQL.Add('Where ID = :P_CARIID');
fibsql.Params[0].AsFloat := HavaleYapilanMiktar - fHavaleUcreti;
fibsql.Params[1].AsInteger := HavaleYapanCariID;
fibsql.ExecQuery;
Sadettin POLAT dedi ki…
-Asım, yaptığımız nesnede habire hatalar çıkıyor.
-Nasıl hatalar abi ?
-Kodu şu şekilde yazdığımızı düşün. bunun sonucu ne olur ?

procedure TForm1.btnHavaleYapClick(Sender: TObject);
var
Havale :THavale;
begin

Havale :=THavale.Create;
try
Havale.Veritabani :=IBDatabase1;
Havale.HavaleYapanCariID :=DBLookupComboBox1.KeyValue;
Havale.HavaleYapilanCariID :=DBLookupComboBox2.KeyValue;
Havale.HavaleYapilanMiktar :=StrToFloat(edit1.Text);
Havale.HavaleYap;
ShowMessage('1. Havale Başarılı');

//başka bir veritabanında da aynı işlemi yapmak istiyoruz. ibdatabase2

Havale.Veritabani :=IBDatabase2;
Havale.HavaleYapanCariID :=DBLookupComboBox1.KeyValue;
Havale.HavaleYapilanCariID :=DBLookupComboBox2.KeyValue;
Havale.HavaleYapilanMiktar :=StrToFloat(edit1.Text);
Havale.HavaleYap;
ShowMessage('2. Havale de Başarılı');

finally
FreeAndNil(Havale);
end;

end;

- 2. havale başarılı olabilir mi Asım ?

Bu blogdaki popüler yayınlar

Yazılımı Oluşturan Bileşenler Nelerdir?

Yazılımı oluşturan bileşenlerden daha önce söz etmiştik. Şimdi bu bileşenlerin neler oldukları üzerinde biraz duralım. Yazılımı oluşturan bileşenler = Mantık + Veri + Belge + İnsan + Program. Bu bileşenlerin az çok neler olduğunu, neleri kapsadığını biliyoruz ama biz yine de kıyısından köşesinden açıklayalım. Zaten bu yazıdaki asıl amaç yazılım bileşenlerinden belgelemenin yerini ve önemi (dökümantasyon) vurgulamak. Mantık = Yazılım herşeyden önce bir işin bilgisayar aracılığı ile yapılması amacına yöneliktir. Bu nedenle bilgisayarlaştırılmak istenen işin mevcut mantığı bir şekilde yazılıma da yansılıtılmak zorundadır. Veri = Her tür yazılım mutlaka bir veri üzerinde çalışmak durumundadır. Veri işlemeyen yazılımın geliştirilmesi söz konusu değildir. Söz konusu olan veri dış ortamdan alınabileceği gibi yazılımın içerisinde de üretilebilir. Zaten yazılımın temel amacı veriyi bilgiye dönüştürmektir. İnsan = Doğal olarak yazılımın insan bileşeni iki boyutludur. Yazıl

Leyse li'l-insâni illâ mâ seâ

"Leyse li'l-insâni illâ mâ seâ" derken Hudâ; Anlamam hiç meskenetten sen ne beklersin daha? Mehmet Akif Ersoy / Durmayalim Leyse li'l-insâni illâ mâ seâ : Necm Süresi 39. Ayet. [İnsan için ancak çalıştığı vardır.] Meskenet: 1 . Miskinlik, beceriksizlik. 2 . Yoksulluk, fakirlik. (Türk Dil Kurumu) Olay zaten yeterince acik. Yan gelip yatma kardesim. Calis. Bu misralar yazildigi donemde bu anlami tasiyordu fakat zaman ilerledikce baska bir gercegi de gozler onune seriyor.Gerci bu gercek cok kapsamli bir kac satirla anlatilabilecek bir sey degil kaldiki benim bilgim de buna yeterli degil zaten. Ben giris cumlelerini verebilirim gerisini arastirmak yaziyi okuyanlara kalmis. (Matrix gibi bisey oldu bu yaw. Neo'nun kahinle bulusup yanindan ayrildiktan sonra Morpheus ile konusma sahnesi.) Yani kisaca sunu demek istiyorum. Ben bu misrayi ilk okudugumda hic birsey anlamadim. Bu misralari anlayabilmek icin kuran mealine ve turkce sozluklere bakmak zorunda k

Yunus sen bu dünyaya niye geldin?

Göçtü Kervan Ah nice bir uyursun uyanmaz mısın Göçtü kervan kaldık dağlar başında Çağrışı tellallar inanmaz mısın Göçtü kervan kaldık dağlar başında Emr-i hac göçeli hayli zamandır Muhammed cümleye dindir imandır Delilsiz gidilmez yollar yamandır Göçtü kervan kaldık dağlar başında Yunus sen bu dünyaya niye geldin Gece gündüz Hakkı zikretsin dilin Enbiyaya uğramaz ise yolun Göçtü kervan kaldık dağlar başında Yunus Emre