
OOP'de Constructors ve Destructors
Yapıcılar ve yıkıcılar önemli kavramlardır.Object-Oriented Programming. Geliştiricilerin, bir nesne oluşturulduğunda ne olacağını ve bir nesneye artık ihtiyaç duyulmadığında ne olacağını kontrol etmelerine yardımcı olurlar. Bu özel yöntemleri anlamak, temiz, düzenli ve güvenilir nesne yönelimli kod yazmak için çok önemlidir.
OOP'da nesneler genellikle gerçek varlıkları, sistem bileşenlerini veya veri modellerini temsil eder. Bir nesne oluşturulduğunda genellikle başlangıç değerlerine, konfigürasyona veya gerekli bağımlılıklara ihtiyaç duyar. Bir kurucu bu başlatma sürecini açık ve otomatik hale getirir. Öte yandan bir yıkıcı, kaynakları temizlemek veya nesne bellekten kaldırılmadan önce son eylemleri gerçekleştirmek için kullanılır.
Giriş
Bu OOP serisinin önceki makalelerinde Object-Oriented Programming’in temel anlamını, sınıflar ve nesneler arasındaki ilişkiyi, özellik ve yöntemlerin rolünü tartışmıştık. Bu yazıda bir adım daha ileri giderek iki özel yönteme odaklanacağız:inşaatçılarveyıkıcılar.
Bu yöntemler normal yöntemler gibi kullanılmadığı için özeldir. Yeni bir nesne oluşturulduğunda yapıcı otomatik olarak çağrılır. Programlama diline ve bellek yönetim sistemine bağlı olarak nesne yok edildiğinde veya programın artık ona ihtiyacı kalmadığında yıkıcı çağrılır.
Yapıcılar ve yıkıcılar nesne yaşam döngüsü yönetimini kolaylaştırır. Bir nesne oluşturmak ve daha sonra birçok değeri manuel olarak ayarlamak yerine, yapıcı, nesnenin geçerli ve kullanıma hazır bir durumda başlatılmasına izin verir. Bu, hataları azaltır ve kodun okunabilirliğini artırır.
Yapıcı Nedir?
biryapıcıbir nesne oluşturulduğunda otomatik olarak çalışan, sınıf içindeki özel bir yöntemdir. Ana amacı nesneyi başlatmaktır. Bu, özelliklere başlangıç değerleri atamak, gerekli verileri hazırlamak veya nesnenin doğru çalışması için ihtiyaç duyduğu bağımlılıkları almak anlamına gelir.
Örneğin, bir User sınıfımız varsa, her kullanıcı nesnesinin bir ada, e-postaya ve role ihtiyacı olabilir. Boş bir nesne oluşturup bu değerleri tek tek ayarlamak yerine doğrudan yapıcıya aktarabiliriz. Bu, nesne oluşturmayı daha düzenli ve daha az hataya açık hale getirir.
Bir yapıcı önemli bir soruyu yanıtlamaya yardımcı olur: Bu nesne başlatıldığında hangi bilgilere ihtiyaç duyar? Bir kurucu tanımlayarak sınıf, onun gerekli verilerini ve başlangıç durumunu açıkça açıklar.
Yapıcılar Neden Önemlidir?
Yapıcılar önemlidir çünkü kontrollü bir şekilde nesnelerin oluşturulmasına yardımcı olurlar. Yapıcılar olmadan geliştiriciler bir nesne oluşturduktan sonra önemli değerleri atamayı unutabilirler. Bu, eksik nesnelere, çalışma zamanı hatalarına ve öngörülemeyen davranışlara yol açabilir.
Yapıcıları kullanmak yazılım kalitesini çeşitli şekillerde artırır:
Nesne oluşturmayı net ve tutarlı hale getirirler.
Gerekli özelliklerin başlangıç değerlerini almasını sağlarlar.
Uygulamanın farklı bölümlerinde tekrarlanan kurulum kodlarını azaltırlar.
Sınıfların anlaşılmasını ve kullanılmasını kolaylaştırırlar.
Bağımlılık enjeksiyonunu ve daha iyi uygulama yapısını desteklerler.
Gerçek yazılım projelerinde yapıcılar genellikle yapılandırma değerlerini, veritabanı hizmetlerini, API istemcilerini, depoları veya bir sınıfın bağlı olduğu diğer nesneleri iletmek için kullanılır.
Yapıcı Örnek Konsepti
Product adında bir sınıf düşünün. Bir ürünün genellikle bir isme, fiyata ve kategoriye ihtiyacı vardır. Bir ürün nesnesi oluşturduğumuzda bu değerlerin hemen mevcut olması gerekir. Bir yapıcı, nesneyi baştan itibaren gerekli tüm verilerle oluşturmamıza olanak tanır.
Kavramsal olarak nesne oluşturma şu şekilde görünebilir:
Product product = new Product("Laptop", 1200, "Electronics");Bu örnekte yapıcı ürün adını, fiyatını ve kategorisini alır. Nesne boş başlamıyor. Anlamlı verilerle başlar, bu da onu daha güvenli ve kullanımı daha kolay hale getirir.
Tam sözdizimi bir programlama dilinden diğerine değişir, ancak fikir aynıdır: Yapıcı, nesneyi oluşturma anında hazırlar.
Varsayılan Yapıcılar
birvarsayılan kurucuherhangi bir argüman gerektirmeyen bir yapıcıdır. Varsayılan değerlere sahip bir nesne oluşturur. Bazı programlama dilleri, geliştiricinin manuel olarak tanımlamaması durumunda otomatik olarak bir varsayılan kurucu oluşturur.
Varsayılan yapıcılar, zorunlu veriler olmadan bir nesne oluşturulabildiğinde kullanışlıdır. Örneğin, bir ayarlar nesnesi varsayılan seçeneklerle başlayabilir ve geliştiricinin bunları daha sonra değiştirmesine izin verebilir.
Ancak varsayılan kurucular dikkatli kullanılmalıdır. Bir sınıfın doğru çalışması için önemli veriler gerekiyorsa, genellikle parametreleri olan bir kurucu kullanmak daha iyidir. Bu, geçersiz veya eksik nesnelerin oluşturulmasını engeller.
Parametreli Oluşturucular
birparametreli yapıcınesne oluşturulduğunda değerleri alır. Bu değerler genellikle özelliklere atanır veya nesne durumunu hazırlamak için kullanılır.
Parametreli yapıcılar gerçek uygulamalarda yaygındır çünkü çoğu nesne veriye ihtiyaç duyar. Bir Müşteri nesnesinin bir isme ve telefon numarasına ihtiyacı olabilir. Bir Sipariş nesnesinin bir müşteriye, ürün listesine ve toplam fiyata ihtiyacı olabilir. Bir DatabaseConnection nesnesinin ana makineye, kullanıcı adına, parolaya ve veritabanı adına ihtiyacı olabilir.
Bu tür yapıcı, gerekli bilgilerin nesneyi oluştururken doğrudan görülebilmesi nedeniyle netliği artırır. Geliştirici, yapıcı parametrelerine bakarak sınıfın neye ihtiyacı olduğunu anlayabilir.
Yapıcılar ve Nesne Durumu
Bir kurucunun en önemli rollerinden biri nesneyi geçerli bir duruma yerleştirmektir. Bir nesne, gerekli özellikleri mevcut olduğunda ve iç kurallarına uyulduğunda geçerli bir durumdadır.
Örneğin bir BankAccount nesnesi hesap sahibi olmadan oluşturulmamalıdır. Fatura öğeleri olmadan bir Fatura nesnesi oluşturulmamalıdır. Uygulama e-posta tabanlı kimlik doğrulama gerektiriyorsa, e-posta olmadan bir Kullanıcı nesnesi oluşturulmamalıdır.
Geliştiriciler yapıcıları doğru kullanarak geçersiz nesne durumlarını önleyebilir. Bu, kodu daha güvenli hale getirir ve farklı yerlerde tekrarlanan doğrulama ihtiyacını azaltır.
Yapıcılar ve Dependency Injection
Yapıcılar yaygın olarak kullanılırDependency Injection. Dependency Injection, bir sınıfa ihtiyaç duyduğu harici hizmetleri veya nesneleri dahili olarak oluşturmak yerine vermek anlamına gelir.
Örneğin, bir UserService sınıfının kullanıcı verilerine erişmek için bir UserRepository'ye ihtiyacı olabilir. Depoyu hizmet içinde oluşturmak yerine depo yapıcı aracılığıyla aktarılabilir. Bu, sınıfın test edilmesini, bakımının kolay olmasını ve belirli uygulamalara daha az bağlı olmasını sağlar.
Yapıcı tabanlı bağımlılık enjeksiyonu, Laravel, Symfony, Spring gibi çerçevelerde ve birçok modern uygulama mimarisinde yaygındır. Temiz kod ilkelerini destekler ve yazılım esnekliğini artırır.
Yıkıcı Nedir?
biryıkıcıbir nesne yok edildiğinde veya program onu kullanmayı bitirdiğinde çağrılan özel bir yöntemdir. Bir yıkıcının amacı genellikle kaynakları temizlemek veya son işlemleri gerçekleştirmektir.
Örneğin, bir yıkıcı bir dosyayı kapatmak, bir veritabanı bağlantısını serbest bırakmak, geçici verileri temizlemek veya son günlükleri yazmak için kullanılabilir. Buradaki fikir, nesneye kaybolmadan önce kendi kendini temizleme şansı vermektir.
Tüm programlama dilleri yıkıcıları aynı şekilde kullanmaz. Bazı dillerde açık yıkıcılar bulunurken, diğerleri çöp toplama veya kaynak yönetimi modellerine dayanır. Ancak genel kavram hâlâ kullanışlıdır: Nesneler bazen yaşam döngülerinin sonunda temizleme mantığına ihtiyaç duyar.
Yıkıcılar Neden Önemlidir
Yıkıcılar, nesneler sonsuza kadar açık kalmaması gereken kaynakları kullandığında önemlidir. Bir dosya açılırsa ve asla kapatılmazsa uygulama sistem kaynaklarını boşa harcayabilir. Bağlantı serbest bırakılmazsa performans sorunlarına neden olabilir. Geçici veriler kaldırılmazsa depolama veya güvenlik sorunları yaratabilir.
Yaygın temizleme görevleri şunları içerir:
Dosyaları okuduktan veya yazdıktan sonra kapatmak.
Veritabanı veya ağ bağlantılarının serbest bırakılması.
Geçici dosyaları veya önbelleğe alınmış verileri kaldırma.
Son günlük mesajlarının yazılması.
Otomatik olarak yönetilmeyen dış kaynakların serbest bırakılması.
Birçok modern dilde bellek temizleme işlemi otomatik olarak gerçekleştirilir. Ancak kaynak temizliği, özellikle dosyalar, yuvalar, akışlar, veritabanı bağlantıları veya harici hizmetlerle çalışırken hala önemlidir.
Yapıcı vs Yıkıcı
Yapıcılar ve yıkıcılar birbiriyle ilişkilidir çünkü her ikisi de nesne yaşam döngüsüne bağlıdır. Yapıcı yaşam döngüsünün başında çalışır, yıkıcı ise sonuna doğru çalışır.
Yapıcı nesneyi hazırlar. Yıkıcı nesneden sonra temizler. Biri başlatmayla ilgili, diğeri ise sonuçlandırmayla ilgili.
Özellik | Oluşturucu | Yıkıcı |
|---|---|---|
Ana amaç | Nesneyi başlat | Kaynakları temizleme |
Çalıştırıldığında | Nesne oluşturulduğunda | Nesne yok edildiğinde |
Ortak kullanım | Özellikleri ve bağımlılıkları ayarlama | Dosyaları kapatın veya kaynakları serbest bırakın |
Yaşam döngüsü aşaması | Nesne yaşamının başlangıcı | Nesne ömrünün sonu |
Bu farkı anlamak, geliştiricilerin yönetimi daha kolay ve kullanımı daha güvenli sınıflar tasarlamasına yardımcı olur.
Gerçek Projelerdeki İnşaatçılar
Gerçek yazılım projelerinde yapıcılar sıklıkla kullanılır. Modellerde, hizmetlerde, denetleyicilerde, depolarda, veri aktarım nesnelerinde ve diğer birçok sınıfta görünürler.
Örneğin bir web uygulamasında bir kontrolör, yapıcısı aracılığıyla hizmetleri alabilir. Bir hizmet, oluşturucusu aracılığıyla depoları alabilir. Bir depo, yapıcısı aracılığıyla bir veritabanı bağlantısı alabilir. Bu açık bir bağımlılık zinciri oluşturur ve uygulama yapısının anlaşılmasını kolaylaştırır.
Yapıcılar aynı zamanda etki alanı modellerinde de faydalıdır. Order sınıfı bir müşteri ve sipariş öğeleri gerektiriyorsa yapıcı bu değerleri doğrudan isteyebilir. Bu, her sipariş nesnesinin oluşturulduğu andan itibaren anlamlı olmasını sağlar.
Gerçek Projelerde Yıkıcılar
Yıkıcılar birçok modern uygulamada yapıcılara göre daha az görünürdür ancak yine de belirli durumlarda faydalıdırlar. Genellikle normal iş mantığından ziyade kaynak yönetimiyle ilgilidirler.
Örneğin, bir sınıf geçici bir dosyayı açarsa, yıkıcı o dosyayı kaldırabilir veya kapatabilir. Eğer bir sınıf hata ayıklama bilgisi yazıyorsa, nesne artık kullanılmadığında yıkıcı son bir mesaj yazabilir.
Ancak geliştiricilerin kritik iş operasyonları için yıkıcılara çok fazla güvenmemeleri gerekir. Bazı dillerde yıkımın kesin zamanı tahmin edilemeyebilir. Önemli eylemler için açık yöntemleri, try-finally bloklarını, bağlam yöneticilerini veya çerçeve destekli yaşam döngüsü yöntemlerini kullanmak genellikle daha iyidir.
Yapıcılarla Yapılan Yaygın Hatalar
Yapıcılar faydalı olmasına rağmen kötüye kullanılabilirler. Yaygın bir hata, yapıcının içine çok fazla mantık koymaktır. Bir yapıcının nesneyi hazırlaması gerekir ancak genellikle uzun veritabanı sorguları, karmaşık hesaplamalar veya harici API çağrıları gibi ağır işlemleri gerçekleştirmemelidir.
Diğer bir hata ise yapıcıların çok fazla parametreyle kullanılmasıdır. Eğer bir yapıcı çok fazla değer gerektiriyorsa, sınıf çok fazla şey yapıyor olabilir. Bu, sınıfın daha küçük sorumluluklara bölünmesi gerektiğinin veya bir yapılandırma nesnesinin kullanılması gerektiğinin bir işareti olabilir.
Yaygın yapıcı hataları şunları içerir:
Eksik veya geçersiz verilere sahip nesneler oluşturma.
Yapıcının içine karmaşık iş mantığı ekleme.
Çok fazla yapıcı parametresi kullanma.
Bunları enjekte etmek yerine yapıcının içinde güçlü bağımlılıklar oluşturmak.
Belirsiz kurulum gereksinimlerini gizlemek için yapıcıları kullanma.
Yıkıcılarla İlgili Yaygın Hatalar
Yıkıcılar dikkatli kullanılmazlarsa sorunlara da neden olabilirler. Bir hata, hemen gerçekleşmesi gereken eylemler için yıkıcılara güvenmektir. Dile bağlı olarak yıkıcı, geliştiricinin beklediği anda çalışmayabilir.
Diğer bir hata ise iş mantığını yıkıcıya koymaktır. Bir yıkıcı genellikle önemli uygulama kararlarına değil, temizlemeye odaklanmalıdır. Örneğin ödeme isteklerinin gönderilmesi, kritik kayıtların güncellenmesi veya kullanıcı verilerinin değiştirilmesi sadece bir yıkıcıya bağlı olmamalıdır.
Mümkün olduğunda yıkıcılardan hata atmaktan kaçınmak da önemlidir, çünkü nesne temizleme sırasındaki hataların işlenmesi ve hatalarının ayıklanması zor olabilir.
Yapıcılar ve Yıkıcılar için En İyi Uygulamalar
Yapıcıların ve yıkıcıların iyi kullanımı kod kalitesini artırabilir. Amaç, nesne oluşturmayı net ve temizliği öngörülebilir tutmaktır.
Yararlı en iyi uygulamalar şunları içerir:
Nesne için temel verileri gerektirmek üzere yapıcıları kullanın.
Yapıcıları basit tutun ve başlatmaya odaklanın.
Yapıcıların içindeki ağır iş mantığından kaçının.
Hizmetler ve depolar için yapıcı bağımlılığı eklemeyi kullanın.
Yıkıcıları çoğunlukla temizleme görevleri için kullanın.
Kritik iş operasyonları için yıkıcılara güvenmeyin.
Nesne yaşam döngüsü kurallarını açık ve anlaşılması kolay tutun.
Bu uygulamaları takip etmek kodun test edilmesini, hata ayıklamasını ve bakımını kolaylaştırır.
Yapıcılar, Yıkıcılar ve Temiz Kod
Yapıcılar ve yıkıcılar yalnızca teknik özellikler değildir. Bunlar aynı zamanda temiz kod tasarımının bir parçasıdır. İyi bir kurucu nesnenin neye ihtiyacı olduğunu iletir. İyi bir yıkıcı, uygulamayı kaynak sızıntılarından ve tamamlanmamış temizlemeden korur.
Bir sınıfın net bir yapıcısı varsa diğer geliştiriciler onu daha kolay kullanabilir. Nesne oluşturulduktan sonra hangi özelliklerin ayarlanması gerektiğini tahmin etmelerine gerek yoktur. Yapıcının kendisi bir belgeleme biçimi haline gelir.
Temizleme sorumlulukları doğru şekilde yerine getirildiğinde uygulama daha kararlı hale gelir. Bu özellikle büyük projelerde, uzun süren süreçlerde, arka plan işlerinde, dosya işleme sistemlerinde ve dış hizmetlerle iletişim kuran uygulamalarda önemlidir.
Sonuç
Yapıcılar ve yıkıcılar Object-Oriented Programming’in temel parçalarıdır. Bir kurucu, bir nesne yaratıldığında onu hazırlarken, bir yıkıcı, nesneye artık ihtiyaç duyulmadığında temizlemeye yardımcı olur.
Yapıcılar nesne başlatmayı iyileştirir, gerekli verileri netleştirir ve bağımlılık eklemeyi destekler. Yıkıcılar, özellikle dosyalar, bağlantılar veya geçici verilerle çalışırken kaynakları yönetmeye ve uygulamaları daha temiz tutmaya yardımcı olur.
Geliştiriciler yapıcıları ve yıkıcıları anlayarak daha iyi sınıflar yazabilir, eksik nesnelerden kaçınabilir, kaynakları daha güvenli bir şekilde yönetebilir ve bakımı daha kolay yazılımlar geliştirebilir. Bu kavramlar kapsülleme, kalıtım, polimorfizm, bağımlılık enjeksiyonu ve tasarım desenleri gibi daha derin OOP konuları için önemli bir temel oluşturur.

