OOP'de Encapsulation

Kapsülleme en önemli prensiplerden biridir.Object-Oriented Programming. Nesnelerin içindeki verileri korumak, bu verilere nasıl erişilebileceğini kontrol etmek ve kodu temiz ve güvenli bir şekilde düzenlemek için kullanılır. Basit bir ifadeyle kapsülleme, bir nesnenin iç ayrıntılarının gizli tutulması ve yalnızca kontrollü yöntemlerle erişime izin verilmesi anlamına gelir.

Bu makalede kapsüllemenin ne anlama geldiği, neden önemli olduğu, erişim değiştiricilerin nasıl çalıştığı ve kapsüllemenin geliştiricilerin sürdürülebilir yazılım uygulamaları oluşturmasına nasıl yardımcı olduğu açıklanmaktadır.

Giriş

Bu OOP serisinin önceki makalelerinde Object-Oriented Programming’in temel fikrini, sınıfları, nesneleri, özellikleri, yöntemleri, yapıcıları, yıkıcıları ve kalıtımı açıklamıştık. Bu kavramlar, geliştiricilerin yazılımı yeniden kullanılabilir ve organize bileşenler kullanarak yapılandırmasına yardımcı olur.

Kapsülleme bu yapıya önemli bir katman daha ekler. Bir nesnenin dahili durumunu korur ve uygulamanın diğer bölümlerinin verileri doğrudan güvenli olmayan veya beklenmedik şekillerde değiştirmesini engeller.

Kapsülleme olmadan yazılımın kontrolü zorlaşabilir çünkü programın herhangi bir kısmı nesne verilerini değiştirebilir. Bu, hatalara, tutarsız değerlere, güvenlik sorunlarına ve bakımı zor kodlara yol açabilir.

Object-Oriented Programming'da Kapsülleme Nedir?

OOP'da kapsülleme, verileri ve davranışı bir sınıf içine sarma ve nesnenin bazı bölümlerine doğrudan erişimi kısıtlama işlemidir. Sınıf, hangi özelliklerin ve yöntemlerin dışarıdan görülebileceğine ve hangi ayrıntıların özel kalması gerektiğine karar verir.

Kapsüllemeyi anlamanın basit bir yolu, bir nesneyi korunan bir birim olarak düşünmektir. Nesne veri içerir ancak uygulamanın diğer bölümleri bu verilere her zaman doğrudan erişmemeli veya bunları değiştirmemelidir. Bunun yerine sınıf tarafından sağlanan genel yöntemleri kullanmaları gerekir.

Örneğin bir kullanıcı nesnesi ad, e-posta, parola ve rol gibi özelliklere sahip olabilir. Bu özelliklerin bazılarına güvenli bir şekilde erişilebilirken, şifre gibi bazılarının da dikkatle korunması gerekmektedir. Kapsülleme bu erişimin kontrol edilmesine yardımcı olur.

Kapsülleme Neden Önemlidir?

Kapsülleme önemlidir çünkü yazılımın güvenliğini, organizasyonunu ve güvenilirliğini artırır. Nesne verilerine kontrolsüz erişimi önler ve geliştiricilerin, verilerin nasıl değiştirilmesi gerektiğine ilişkin net kurallar tanımlamasına olanak tanır.

Gerçek uygulamalarda veriler çoğunlukla belirli koşulları takip etmelidir. Örneğin, sistem kredili mevduat hesabına izin vermediği sürece hesap bakiyesi negatif olmamalıdır. Bir ürünün fiyatı sıfırın altında olmamalıdır. Bir kullanıcı e-postası geçerli bir formatta olmalıdır. Kapsülleme, bu kuralların sınıf dışından doğrudan değişikliklere izin vermek yerine yöntemlerin içine yerleştirilmesine olanak tanır.

Bu, kodu daha öngörülebilir hale getirir. Tüm değişiklikler kontrollü yöntemlerden geçtiğinde verileri doğrulamak, sorunlarda hata ayıklamak ve nesneyi geçersiz durumlardan korumak daha kolay hale gelir.

Kapsülleme ve Veri Koruma

Kapsüllemenin ana hedeflerinden biri veri korumasıdır. OOP'da nesneler genellikle önemli bilgileri depolar. Bu bilgiler herkese açıksa ve doğrudan değiştirilebiliyorsa uygulama hatalara açık hale gelir.

Örneğin bir banka hesabını temsil eden bir sınıf düşünün. Denge özelliği halka açıksa programın herhangi bir kısmı onu doğrudan değiştirebilir. Bu, bakiyenin iş kuralları kontrol edilmeden geçersiz bir değere ayarlanabileceği anlamına gelir.

Kapsülleme, dengeyi özel veya korumalı hale getirerek bu sorunu çözer. Sınıf daha sonra para yatırma ve çekme gibi genel yöntemleri sağlayabilir. Bu yöntemler bakiyeyi güncellemeden önce tutarı kontrol edebilir.

Bu yaklaşım verileri korur ve nesneyi geçerli bir durumda tutar.

Kapsüllemede Erişim Değiştiricileri

Erişim değiştiricileri, bir sınıf içindeki özelliklerin ve yöntemlerin görünürlüğünü kontrol etmek için kullanılan anahtar kelimelerdir. Sınıf dışından nelere erişilebileceğini, nelere yalnızca sınıf içinden erişilebileceğini ve alt sınıfların nelere erişebileceğini tanımlarlar.

Object-Oriented Programming'daki en yaygın erişim değiştiriciler şunlardır:

  • Herkese açık:Özelliğe veya yönteme her yerden erişilebilir.

  • Özel:Özellik veya yönteme yalnızca aynı sınıf içinden erişilebilir.

  • Korumalı:Özellik veya yönteme aynı sınıf içinden ve alt sınıflar tarafından erişilebilir.

Doğru erişim değiştiriciyi seçmek, temiz OOP kodu yazmanın önemli bir parçasıdır. Geliştiriciler, çok fazla dahili ayrıntıyı ortaya çıkaracağı ve nesne üzerindeki kontrolü azaltacağı için her şeyi herkese açık hale getirmekten kaçınmalıdır.

Herkese Açık Üyeler

Public üyelere sınıf dışından erişilebilir. Genellikle uygulamanın diğer bölümlerinin gerçekleştirmesine izin verilen eylemleri temsil eden yöntemler için kullanılırlar.

Örneğin, bir kullanıcı sınıfının updateEmail adında genel bir yöntemi olabilir. Bu yöntem sınıfın dışından çağrılabilir, ancak yine de dahili özelliği değiştirmeden önce e-postayı doğrulayabilir.

Genel yöntemler nesnenin dış arayüzünün bir parçasıdır. Uygulamanın diğer bölümlerinin nesneyle nasıl iletişim kurabileceğini tanımlarlar.

Özel Üyeler

Özel üyelere yalnızca tanımlandıkları sınıf içinden erişilebilir. Doğrudan dışarıdan değiştirilmemesi gereken hassas veriler veya dahili mantık için yaygın olarak kullanılırlar.

Örneğin, bir parola özelliğinin genellikle özel olması gerekir. Uygulamanın diğer bölümleri uygulamayı doğrudan okumamalı veya değiştirmemelidir. Bunun yerine sınıf, bir parola ayarlama, karma oluşturma veya doğrulama için yöntemler sağlayabilir.

Özel üyeler uygulama ayrıntılarının gizlenmesine yardımcı olur. Bu, genel yöntemler aynı kaldığı sürece geliştiricilerin uygulamanın geri kalanını bozmadan dahili mantığı daha sonra değiştirebilecekleri anlamına gelir.

Korunan Üyeler

Korumalı üyeler özel üyelere benzer ancak bunlara alt sınıflar tarafından da erişilebilir. Kalıtım kullanıldığında ve alt sınıfların paylaşılan özelliklere veya yöntemlere kontrollü erişime ihtiyaç duyduğu durumlarda kullanışlıdırlar.

Örneğin, bir temel çalışan sınıfı, korunan bir maaş özelliği veya ikramiyelerin hesaplanması için korunan bir yöntem tanımlayabilir. Yönetici veya geliştirici gibi alt sınıflar bu üyeleri dış dünyadan gizli tutarken kullanabilir.

Korumalı erişim dikkatli kullanılmalıdır. Kalıtım açısından yararlı olabilir ancak alt sınıflara çok fazla maruz kalmak sistemin sürdürülmesini zorlaştırabilir.

Alıcılar ve Ayarlayıcılar

Alıcılar ve ayarlayıcılar, özel veya korumalı özellikleri okumak ve güncellemek için kullanılan yöntemlerdir. Nesne verilerine kontrollü erişim sağlarlar.

Alıcı, bir özelliğin değerini döndürürken, ayarlayıcı değeri günceller. Ayarlayıcıları kullanmanın yararı, dahili verileri değiştirmeden önce doğrulama kurallarının eklenebilmesidir.

Örneğin bir ürün sınıfının özel fiyat özelliği olabilir. Halka açık ayarlayıcı yöntem, fiyatı kaydetmeden önce fiyatın sıfırdan büyük olup olmadığını kontrol edebilir. Bu, geçersiz değerlerin nesneye girmesini önler.

Ancak geliştiriciler her özellik için alıcıları ve ayarlayıcıları otomatik olarak oluşturmamalıdır. İyi kapsülleme, yalnızca gerekli olanı ortaya çıkarmak ve gereksiz ayrıntıları gizli tutmak anlamına gelir.

PHP’de Kapsülleme Örneği

Aşağıdaki örnek, basit bir PHP sınıfında kapsüllemenin nasıl kullanılabileceğini gösterir:

class BankAccount
{
    private float $balance = 0;

    public function deposit(float $amount): void
    {
        if ($amount <= 0) {
            throw new InvalidArgumentException('Deposit amount must be greater than zero.');
        }

        $this->balance += $amount;
    }

    public function withdraw(float $amount): void
    {
        if ($amount <= 0) {
            throw new InvalidArgumentException('Withdraw amount must be greater than zero.');
        }

        if ($amount > $this->balance) {
            throw new InvalidArgumentException('Insufficient balance.');
        }

        $this->balance -= $amount;
    }

    public function getBalance(): float
    {
        return $this->balance;
    }
}

Bu örnekte denge özelliği özeldir. Sınıfın dışından doğrudan değiştirilemez. Bunu değiştirmenin tek yolu para yatırma ve çekme yöntemleridir.

Bu, hesabı geçersiz işlemlere karşı korur ve bakiyenin tutarlı kalmasını sağlar.

Gerçek Yazılım Projelerinde Kapsülleme

Kapsülleme birçok gerçek yazılım projesinde, özellikle de açık kurallara ve güvenilir davranışa ihtiyaç duyan sistemlerde kullanılır. Web uygulamalarında, iş sistemlerinde, APIs, e-ticaret platformlarında, bankacılık sistemlerinde ve kurumsal yazılımlarda yaygındır.

Örneğin bir e-ticaret sisteminde bir sipariş nesnesi; kalemleri, toplam fiyatı, indirimi, ödeme durumunu ve nakliye durumunu içerebilir. Bu değerler uygulamanın farklı kısımlarından rastgele değiştirilmemelidir.

Bunun yerine sipariş sınıfı addItem, applicationDiscount, markAsPaid ve markAsShipped gibi yöntemler sağlayabilir. Her yöntem gerekli iş kurallarını ve doğrulama mantığını içerebilir.

Bu, siparişle ilgili davranışın sipariş nesnesinin içine yerleştirilmesi nedeniyle sistemin anlaşılmasını kolaylaştırır.

Kapsülleme ve Kod Bakımı

Kapsülleme, bir sınıfın dahili uygulamasını uygulamanın diğer bölümlerinin onu kullanma biçiminden ayırdığı için sürdürülebilirliği artırır. Dahili ayrıntılar gizlendiğinde, geliştiriciler tüm sistemi etkilemeden sınıfı güncelleyebilir veya iyileştirebilir.

Örneğin, bir sınıf bugün verileri bir formatta saklayabilir ve daha sonra başka bir formatı kullanabilir. Uygulamanın diğer bölümleri yalnızca genel yöntemlerle etkileşime giriyorsa dahili değişiklik, kodun geri kalanında değişiklik yapılmasını gerektirmeyebilir.

Bu, mevcut özelliklerin bozulma riskini azaltır ve yazılımın zaman içinde yeniden düzenlenmesini kolaylaştırır.

Kapsülleme ve Temiz Kod

Temiz kod yalnızca kısa işlevler veya okunabilir adlar yazmakla ilgili değildir. Bu aynı zamanda sorumlulukların kontrol edilmesi ve uygulamanın farklı bölümleri arasındaki gereksiz bağımlılıkların azaltılmasıyla da ilgilidir.

Kapsülleme, verilere doğrudan erişimi sınırlayarak ve yalnızca anlamlı davranışları açığa çıkararak temiz kodu destekler. Sınıf, harici kodun özellikleri doğrudan değiştirmesine izin vermek yerine iş eylemlerini açıklayan yöntemler sağlar.

Örneğin, markInvoiceAsPaid'i kullanmak genellikle bir fatura durumu özelliğini doğrudan ödendi olarak ayarlamaktan daha anlaşılırdır. Yöntem adı, eylemin amacını açıklar ve sınıfın ilgili mantığı dahili olarak ele almasına olanak tanır.

Kapsülleme ve Soyutlama

Kapsülleme ve soyutlama birbiriyle ilişkili kavramlardır ancak aynı şey değildir. Kapsülleme, verileri korumaya ve dahili ayrıntılara erişimi kontrol etmeye odaklanır. Soyutlama, karmaşıklığı gizlemeye ve yalnızca temel davranışı göstermeye odaklanır.

Kapsülleme şu soruyu yanıtlıyor: Bu verilere veya yönteme kimler erişebilir? Soyutlama şu soruyu yanıtlıyor: Bu sınıfın kullanıcısının neyi bilmesi gerekiyor?

Uygulamada her iki prensip de sıklıkla birlikte çalışır. Bir sınıf, soyutlama yoluyla basit bir genel arayüz sağlarken aynı zamanda kapsülleme kullanarak dahili verilerini gizleyebilir.

Kapsüllemede Yaygın Hatalar

Yaygın bir hata, tüm mülklerin kamuya açık hale getirilmesidir. Bu, sınıfın kontrolünü ortadan kaldırır ve harici kodun nesneyi güvenli olmayan şekillerde değiştirmesine izin verir.

Bir diğer hata ise düşünmeden her mülk için alıcılar ve ayarlayıcılar oluşturmaktır. Her özel mülkiyetin bir kamu alıcısı ve belirleyicisi varsa, sınıf yine de iç yapısının çoğunu açığa çıkarabilir.

Üçüncü bir hata, iş kurallarını sınıfa aitken sınıfın dışına yerleştirmektir. Örneğin, bir sipariş durumunu değiştirmeye ilişkin kurallar farklı dosyalara yayılmışsa kodun bakımı zorlaşır.

İyi kapsülleme, ilgili verileri ve davranışları bir arada tutar ve yalnızca nesne için anlamlı olan işlemleri ortaya çıkarır.

Kapsülleme için En İyi Uygulamalar

Kapsüllemeyi doğru kullanmak için geliştiricilerin net sorumluluklara sahip sınıflar tasarlaması gerekir. Her sınıf kendi iç durumunu korumalı ve bu durumla etkileşime geçmek için anlamlı yöntemler sağlamalıdır.

Yararlı en iyi uygulamalar şunları içerir:

  • Kamuya açık hale getirilmesi için güçlü bir neden olmadığı sürece mülkleri özel tutun veya koruyun.

  • Anlamlı eylemleri temsil etmek için genel yöntemleri kullanın.

  • Dahili özellikleri değiştirmeden önce verileri doğrulayın.

  • Gereksiz dahili ayrıntıları açığa çıkarmaktan kaçının.

  • Alıcıları yalnızca harici kodun gerçekten bir değeri okuması gerektiğinde kullanın.

  • Ayarlayıcıları dikkatli kullanın ve gerektiğinde doğrulamayı ekleyin.

  • İş kurallarını kontrol ettikleri verilere yakın tutun.

Bu uygulamalar test edilmesi, yeniden kullanılması ve bakımı daha kolay sınıfların oluşturulmasına yardımcı olur.

Kapsülleme Yeni Başlayanlar İçin Neden Önemlidir?

Yeni başlayanlar için kapsülleme, kodu uzatan ekstra bir kural gibi görünebilir. Ancak uygulamalar büyüdükçe kapsüllemenin değeri ortaya çıkıyor.

Küçük programlar, mülkler herkese açık olduğunda ve veriler doğrudan değiştirildiğinde bile çalışabilir. Ancak daha büyük projelerde kontrolsüz erişim birçok gizli sorun yaratabilir. Kapsülleme, net bir yapı oluşturarak bu sorunların erkenden önlenmesine yardımcı olur.

Kapsüllemeyi öğrenmek aynı zamanda yeni başlayanların profesyonel yazılım tasarımını anlamalarına da yardımcı olur. Çoğu modern çerçeve ve tasarım modeli, kontrollü erişim ve iyi tanımlanmış nesne davranışı fikrine dayanır.

Sonuç

Kapsülleme, verileri korumaya, erişimi kontrol etmeye ve yazılım davranışını düzenlemeye yardımcı olan Object-Oriented Programming’in temel ilkesidir. Kapsülleme, dahili ayrıntıları gizleyerek ve yalnızca gerekli yöntemleri açığa çıkararak kodu daha güvenli, daha temiz ve bakımı daha kolay hale getirir.

Herkese açık, özel ve korumalı gibi erişim değiştiricileri, geliştiricilerin sınıf üyelerinin nasıl kullanılması gerektiğine karar vermesine olanak tanır. Doğru uygulandığında kapsülleme geçersiz veri değişikliklerini önler, iş kurallarını destekler ve yazılım projelerinin uzun vadeli kalitesini artırır.

OOP öğrenen herhangi bir geliştirici için kapsüllemeyi anlamak çok önemlidir. Temiz nesne yönelimli tasarımın temellerinden biridir ve profesyonel, sürdürülebilir ve ölçeklenebilir kod yazmaya yönelik önemli bir adımdır.