Eğitim Mh. Ahsen Çıkmazı Sk. Sadıkoğlu 5 Plaza No:12/41
Hasanpaşa, Kadıköy - İstanbul / Türkiye

Interposer Class Nedir, Nasıl Kullanılır

İşte bunun gibi durumlarda sizden "YAPISAL OLARAK" mevcut bir şeyi değiştirmeniz isteniyorsa bu noktada devreye Interposer sınıflar giriyor. Peki bu Interposer Sınıf denen şey tam olarak nedir? Cevap basit: Aslında, sınıfın kendisini yine kendisinden türetmektir diye özetleyebiliriz.

Interposer Class Nedir, Nasıl Kullanılır

Interposer kelimesinin karşılığı aracı, aracılık yapan demektir. Yani başlık aslında “Aracı Sınıf Nedir” şeklinde de yazılabilirdi.

Bir Interposer Sınıfı, (hiyerarşik anlamda konuşacaksak) bir sınıfın (kendisinden türediği) bir ata sınıf ile bu sınıfın türüne ait bir nesnenin beyanı arasında konumlandırılış bir “Aracı sınıftır”. Ana karakteristiği, ata sınıf ile aynı isme sahip olmasıdır. Bu sayede uygulamalarda ata sınıfın kullanıldığı durumlarda süreci basitleştirmek hedeflenmiştir. Bu teknik aslında 1998’den beri var ve Delphi ile yeteri kadar haşırneşir olanların çok sık kullandığı bir teknik diyebilirim.

Bunu bir hikaye üzerinden açıklamaya çalışayım; Mesela, diyelimki bir uygulamanız var ve bu uygulamanızın bir çok yerinde TPanel nesnesini kullanmışsınız. Bir vakit sonra sizden istisnasız, bu uygulamadaki tüm panellerin sağ üst köşesine bir kapatma butonu koymanız isteniyor ve size deniliyor ki; “Kardeş, biz bu kapatma butonunu koyuyoruz ama kullanıcılar bunu beğenmezse bu talepten vaz da geçebiliriz” diyorlar… Al bakalım, sakal mı bıyık mı! Bu problemi nasıl çözeriz?

Normalde böyle bir durumda tasarım ekranını açıp tüm TPanel nesnelerinin sağ üst köşesine tek tek buton ekler ve içine de ilgili kodu yazarsınız. Peki, güzel… Ya projenizde form sayısı onlarca, hatta yüzlerceyse, o zaman ne olacak? Tüm bu TPanellere aynı işlemi tek tek yapmak bariz bir şekilde hamallık değil de nedir?

Bazı arkadaşlar “Class Helper” tekniğine başvurmak isteyebilir ama hepimiz biliyoruz ki Sınıf Yardımcıları sadece yardım ettikleri sınıfın yerel değişkenleri ve property’leri üzerinde işlem yapabiliyor, asıl nesnenin private bölümündeki değişkenlere erişimde sıkıntı yaşatıyor. Ayrıca Class Helper’larda yeni bir değişken tanımlayamazsınız asıl sınıfın mevcudunda olanları kullanmak durumundasınız. Interposer Class ile Class Helper arasındaki bu temel fark sizin Class Helper veya Interposer Class arasındaki tercihinizi etkiler… Dolayısıyla şimdiki senaryoya uymayan bir durum olduğu için bu noktada class helper tekniği kullanışlı bir seçenek değildir…

Diğerleri de “TPanel’den türetilmiş başka bir tip tanımlarız” diyebilir, yine de tüm formları tek tek gezmeniz ve ilgili eşleşmeleri tek tek düzeltmeniz gerekir. Yani sonuç olarak yine dönüp dolaşıp bu hamallık sekansına geri geliyoruz…

Bunun daha basit bir çözümü yok mu? Yani bu hamallıktan kurtulamayacak mıyız? Hamallıktan kurtuluş yok ama yükümüzü buzdolabı ölçeğinden, aspirin kutusu ölçeğine kadar küçültebiliriz…

İşte bunun gibi durumlarda sizden “YAPISAL OLARAK” mevcut bir şeyi değiştirmeniz isteniyorsa bu noktada devreye Interposer sınıflar giriyor. Peki bu Interposer Sınıf denen şey tam olarak nedir? Cevap basit: Aslında, sınıfın kendisini yine kendisinden türetmektir diye özetleyebiliriz.

Yukarıdaki senaryoyu ele alacak olursak yine o çerçevede bir örneklendirme yapalım.

Yapacağımız şey çok basit, projemizdeki tüm TPanel nesnelerinin sağ üst köşesine bir buton koyacağız ve bu butona basıldığında TPanel nesnesi kendisini imha edecek. Normalde böyle bir özellik TPanel nesnesinde yok ve bizden bu özellik projedeki tüm TPanel nesnelerinde olsun isteniyor…

Bunun için adı InterposerObjects adlı boş bir unit oluşturuyoruz ve içini aşağıdaki gibi dolduruyoruz. Açıklamalar ise kod içinde devam ediyor;

unit InterposerObjects;

interface

uses
   Vcl.StdCtrls    //  TButton
 , System.Classes  //  TComponent
 , Vcl.Controls    //  Anchors
 , Vcl.ExtCtrls    //  TPanel normalde bu unit'te tanımlıdır. Biz bu unitteki TPanel'e yeni bir özellik ekleyeceğiz aşağıda...
 ;

type
 TPanel = class(Vcl.ExtCtrls.TPanel)                             // Bu bizim INTERPOSER sınıfımız oluyor.
   private
     FButon: TButton;                                            // Gerçek sınıfta olmayan bir buton nesnemiz var
   protected
     procedure PaneliYokEt(Sender: TObject);                     // Yine Gerçek sınıfta olmayan bir olay tanımlıyoruz.
                                                                 // Bunun görevi paneli yok etmek olacak...
   public
     constructor Create(AOwner: TComponent); override;           // Butonumuzu bu noktada oluşturuyoruz...
     destructor Destroy; override;                               // Butonumuzu bu noktada yok ediyoruz...
 end;

implementation

uses
   System.SysUtils
 , Vcl.Dialogs
 ;

{ TPanel }

constructor TPanel.Create(AOwner: TComponent);
begin
 // Bu kısım inheritance / miras alma yoluyla klasik TPanel'de ne varsa onu zaten üretiyor.
 inherited Create(aOwner);


 // Bu noktadan sonrasında ise geliştirdiğimiz sınıfımızda yeni butonumuzu yerleşik olarak oluşturuyoruz
 FButon := TButton.Create(Self);
 with  FButon do begin
       Parent  := Self;
       Width   := 20;
       Height  := 20;
       Caption := 'xx';
       Top     := 0;
       Left    := Self.Width - 20;
       Anchors := [akTop, akRight];
       OnClick := PaneliYokEt;
 end;
end;

destructor TPanel.Destroy;
begin
 // Önce yeni butonumuzu yok ediyoruz
 FreeAndNil(FButon);


 // sonra yine miras yoluyla klasik yok etme prosedürünü çağırıyoruz...
 inherited Destroy;
end;

procedure TPanel.PaneliYokEt(Sender: TObject);
begin
 ShowMessage('INTERPOSER SINIF aracılığıyla böyle bir yetenek kazandırmış olduk...');
 Destroy; // ve TPANEL kendi kendini yok eder...
end;

end.

Bu noktadan sonra ise yapacağımız tek bir şey var. Bu uniti projedeki tüm pas dosyalarının INTERFACE bölümüne eklemek olacak. Yalnız burada dikkat etmemiz gereken bir nokta var o da şu, normalde TPanel “Vcl.ExtCtrls.pas” dosyasında tanımlıdır, biz ise kendi unitimizi bu unitten hemen sonra eklemeliyiz yoksa yaptıklarımız bir işe yaramaz.

unit Ana_;

interface

uses
   Winapi.Windows, Winapi.Messages
 , System.SysUtils, System.Variants, System.Classes
 , Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs
 , Vcl.StdCtrls
 , Vcl.ExtCtrls             // TPanel normalde bu unit'te tanımlıdır...
 , InterposerObjects        // YAPMAMIZ GEREKEN İSE SADECE BU UNİTİ BURAYA EKLEMEKTİR...
 ;

type
 TForm2 = class(TForm)
   Panel1: TPanel;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

end.

Tasarım ekranında görmeseniz bile projenizi çalıştırdığınızda gördüğünüz her TPanel nesnesinin sağ üst köşesinde bir kapatma butonuna sahip olduğunuzu göreceksiniz.

Faydalı olması dileğiyle,

Uğur PARLAYAN

1976 İstanbul doğumlu yazar, yeniliğe ve teknolojiye karşı aşırı ilgisi nedeniyle ortaokul yıllarında tanıştığı programlamayı profesyonel düzeyde devam ettirmektedir. 2005 yılından bu yana perakende, hukuk, lojistik ve makine haberleşmesi konuları başta olmak üzere çeşitli masaüstü ve internet tabanlı yazılımlar geliştirmiştir. Öğrenmenin, yeniliklere açık olmanın bu mesleğin temel taşlarından birisi olduğunun farkında olan yazarımız 2016 Yılında Rubicube Yazılım, Donanım ve Teknoloji Hizmetleri Limited Şirketini kurmuş ve çalışmalarını bu şemsiye altında devam etmektedir.

Yorum yapabilmek için giriş yapmalısınız