PIMPL Idiomu
Merhaba arkadaşlar,
Sizlere Pointer İmplementation yani Pimpl idiomundan bahsetmek istiyorum.
PIMPL, Idiom Pointer to Implementation ifadesinin kısaltılmış halidir.
Bu idioma opaque pointer idiomu da denir.
Sizler de bazı projelerinizin header dosyalarında tanımlamış olduğunuz class içerisinde, başka header dosyalarında tanımlamış olduğunuz tipleri kullanmak durumunda kalmışsınızdır.
Bunun için ilk üretilen çözüm ilgili tip tanımlamasının olduğu header dosyasını kendi header dosyanıza include etmek olur. Bu durumda sizin ihtiyaç duymadığınız çok fazla tanım, dahil ettiğiniz header dosyasına tanımlanmış olur. Kendi classınızın bulunduğu header dosyasını da başka modüllerde include ettiğinizde information hiding prensibinden çokça uzaklaşmış olursunuz ve aynı zamanda derlenme sürelerinizi ciddi şekilde arttırmış olursunuz.
Ne demek istediğimi uygulama üzerinden anlatayım ;
3 adet class oluşturalım ve bunlar Class1.h, Class2.h ve Class3.h içerisinde bulunsunlar.
Her classın içerisinde yukarıdaki gibi Func isminde bir fonksiyon bulunsun.
Yukarıda görüldüğü gibi main.h içerisinde Myclass isminde bir class tanımlaması yapmak istedik. Classın private bölümünde ise Class1, Class2 ve Class3 tipinde A,B ve C classlarını tanımlamak isedik. iligli classların bu modülde tanımlı olabilmesi için classların bulunduğu Class1.h, Class2.h ve Class3.h header dosyalarını projemize include etmek zorunda kaldık.
Ancak bu header dosyalarında işimize yaramayan modülümüze dahil etmek istemediğimiz tanımlamaları da kendi modülümüze dahil etmiş olduk.
Bu durumda çok fazla bağımlılık oluşmuş olur ve derleme süresi çok fazla uzamış olur.
Bildiğiniz gibi C++ header dosyalarında sınıfların değişkenleri ve fonksiyonları tanımlanmaktadır. Bu yüzden header dosyasında bir değişiklik yapılırsa ilgili header dosyasını include eden diğer tüm modüller yeniden derlenmek durumunda kalacaktır. Bu da büyük projelerde ciddi zaman alan bir durum demek olacaktır.
İşte burada pimpl idioumu devreye giriyor…
Yukarıdaki kodumuzu pimpl idioumu uygulayarak yeniden revize edelim.
main.h dosyamızı aşağıdaki gibi revize edelim;
Yukarıda gördüğümüz gibi sınıfımızın private bölümünde Pimpl isimli bir struct tanımladık. Idiomu uygulamak için bu sınıf türünden bir pointera ihtiyacımız var ancak bunu raw pointer olarak tanımlamaktan kaçınarak smart pointer olarak tanımladık. Yukarıda görüldüğü gibi bu header dosyasında bulunan include ifadelerini kaldırdık.
Şimdi de main.c dosyamıza bakalım ;
Yukarıda gördüğümüz gibi sınıfımıza dahil etmek istediğimiz Class1, Class2 ve Class3 isimli header dosyalarnı source dosyamızda include ettik. Bu sayede header dosyamızda tanımlamış olduğumuz include ifadelerinden kurtulmuş olduk.
Tanımlamış olduğumuz Structımızda ise nesnemize dahil etmek istediğimiz class üyelerimizi ekledik. Görüldüğü gibi Myclass fonksiyonumuz içerisinde ilgili classlara erişmek istediğimizde bu işi tanımlamış olduğumuz mp pointerı üzerinden gerçekleştirdik. Bu sayede #include işlemimizi source dosyamıza taşımış olduk.
Bu idiomun bize sunmuş olduğu önemli avantajlar vardır.
Derleme bağımlılıklarını en aza indirir, Interface ve uygulamalar ayrılmış olur ve Portability yani taşınabilirlik sağlanmış olur.
Ayrıca PIMPL idiomu ile sınıf içerisindeki private tanımlamaları diğer sınıflardan tam olarak izole etmiş oluruz. Buda demek oluyorki ilgili header dosyası değiştiğinde ilgili bütün sınıfın yeniden derlenmesi yerine sadece değişiklik yapılan sınıf yeniden derlenecektir.
Tabi bu idiomun bize sağlamış olduğu maliyetler de var.
Herbir PIMPL sınıfı için ayrı ayrı bellek kullanımı gerekeceğinden dolayı, uygulamadaki bellek kullanımı artacaktır.
Ayrıca ilgili class üyelerine doğrudan erişmek yerine bir pointer üzerinden erişileceğinden dolayı ayrı bir maliyette buradan oluşacaktır.