İleri Programlama Dersi 1. Ünite Özet
Nesneye Yönelik Programlamaya Giriş
- Özet
- Sorularla Öğrenelim
Nesneye Yönelik Programlama Yaklaşımı
Yazılımlar, günlük hayatta karşılaşılan problemlerin çözülmesi için cihazların hızlı ve doğru çalışması için yazılmaktadır. Günümüzde bir çok cihaz bilgisayarların yerini almış durumdadır. Bu cihazların hızları ve kapasiteleri arttıkça programlar da bunlara uygun olacak şekilde gelişmektedir. Bu gelişim ve değişim nedeniyle yazılım geliştirme yöntemleri de değişmiştir ve çeşitli yazılım geliştirme yaklaşımları ortaya çıkmıştır. En çok bilinen ve en önemli yaklaşımlardan birisi “nesneye yönelik yazılım geliştirme” yaklaşımıdır.
Nesneye Yönelik Programlama: Kısaca bir programlama yaklaşımıdır. 1960’lı yılların sonuna doğru ortaya çıkan bu yaklaşım, o dönemin yazılım dünyasında beliren bir bunalımın sonucudur. Yazılımların karmaşıklığı ve boyutlarının sürekli artması ve aynı zamanda belli bir nitelik düzeyinin korunması için gerekli bakım maliyeti, zaman, çaba vb. unsurların sürekli artması sonucu nesneye yönelik programlama yaklaşımı çözüm olarak geliştirilmiştir.
Nesneye yönelik programlama yaklaşımı dışında Bulunan diğer yaklaşımlar aşağıda sıralanmıştır.
- Yapısal Programlama (Programming),
- Bileşen Tabanlı Yazılım Geliştirme (Component Based Software Development),
- Görünüm Yönelimli Programlama (Aspect Oriented Programming)
Bunlar kendisinden önceki ve sonraki yaklaşımlara altyapı oluşturmuş ve geniş bir kullanım alanı bulmuşlardır.
Problemin uygun bir şekilde bilgisayara aktarılması gerçek hayattaki problemlerin bilgisayar ortamında çözülebilmesi için gerekliliktir. Bu aşama modelleme aşamasıdır. Modelleme, oluşturulan model veya modeller üzerinde sistemin görünüşü, davranışı ya da bazı durumlarda verdiği tepkilerin gözlemlenmesidir. Bilgisayar ortamında oluşturulacak model gerçeğe ne kadar yakın olursa programlama da o kadar kolay olacaktır, bu yüzden nesneye yönelik uygulama yaklaşımı gerçek hayattaki problemin gerçekte var olan nesneler ve bu nesneler arasındaki ilişkilerden oluşturulmasını ilke edinir. Bu yönüyle, son yılların en dinamik ve verimli programlama yaklaşımıdır. Nesneye yönelik programlama yaklaşımı günümüz yaşantısında insanların uzmanlaştığı gibi, kodlama aşamasında ekip içerisinde de farklı görevler oluşturarak bir anlamda kod fabrikaları oluşturulmuştur. Bu örnekte bahsedilen fabrikalar birer “sınıf (class)”, ürettiği ürünler ise “nesne (object)” olup nesneye yönelik programlama yaklaşımının temel kavramlarını oluşturmaktadır.
Ürünlerin detaylarının belirlendiği, tıpkı sabun kalıbı gibi, sabun kalıbına verilen şekil ve detaylar sonrasında o kalıptan istenilen sayı kadarınca sabun üretilebilmektedir. Buradaki sabun kalıbı sınıfı, o kalıpça üretilen sabunlar ise nesneleri oluşturmaktadır. Özetle sınıf, o sınıftan bütün varlıkların ortak özellik ve davranışlarını belirleyen bir yapıdır. Nesne ise, ait olduğu sınıftan gelen özelliklerin belli olduğu, sınıfı için tanımlı olan davranışları nasıl sergilediğinin bilindiği, somut olarak var olan bir kimliği olan varlık olarak düşünülebilir. Sınıfın yaratılan bir örneğine, örnek nesne (instance) ismi verilmektedir. Her nesnenin belli bir takım özellikleri ve işlevselliğini sağlayan davranışları vardır. Nesneye yönelik programlama yaklaşımında nesneler, özellikler (properties) ve metotlar (methods) a sahiptir. Nesnelerdeki karakteristikler, özellikleri ve gerçekleştirebileceği eylemler de metot adını almaktadır. Örneğin bir otomobil nesnesinin hız bilgisi, vites bilgisi özelliklerini, aracın hızlanması, yavaşlaması gibi eylemler ise metotlarını temsil eder. Bir nesnenin yeteneklerine metot ismi verilmektedir. Her bir metot, nesnenin yapabileceği bir davranışı simgelemektedir. Nesneye yönelik programlama yaklaşımı içerisindeki en önemli yapı nesne olduğu için yapı nesne odaklı olup belirli bir sıraya göre gerçekleşmektedir. Bu sıra içerisinde nesneler tasarlanır, oluşturulur ve yapı içerisinde bu nesneler kullanılır. Nesneler somut veya soyut varlıklar olup birbirleriyle iletişime geçebilmektedir. Örneğin, kalem kutusu sınıfı aynı zamanda kalem sınıfıyla ortaklık (association) kurmak durumundadır. Bu ilişki “kalem kutusu kalemlere sahiptir” şeklinde bir ilişki olup sahiplik (has a) ilişkisi olarak adlandırılır. Eğer bir nesne, her zaman bir diğer nesneyi de etkiliyorsa ya da var olmak için diğerine ihtiyaç duyuyorsa o zaman burada da bir bağımlılık (dependency) ilişkisi vardır. Bağımlılık ilişkisine örnek olarak otomobil nesnesiyle, tekerlek nesnesini verebiliriz
Nesneye Yönelik Çözümleme ve Tasarım
Çözümleme, sistemin ne yapması gerektiğinin belirlendiği aşamadır. Bunun için sistemin tanınması ve istenilen gereksinimlerin iyi anlaşılması önemlidir. Nesneye yönelik çözümleme sınıflar ve nesneler kullanılır.
Tasarım aşaması ise, sistemin nasıl gerçekleştirileceği sorusunun yanıtlandığı aşamadır. Bu aşama bir anlamda modelin ortaya çıktığı aşamadır. Tasarım için de sınıflar ve nesneler kullanılır. Tasarım aşaması, genellikle sistemin çeşitli açılardan görünüşlerini ifade eden UML (birleşik modelleme dili) diyagramlarıyla sonlanır. Bu aşama sonrasında ortaya çıkan model, kullanılacak olan uygun programlama diliyle ifade edilecek şekilde kodlanır. Model içerisindeki her aşamanın programlama dilinde bir karşılığı olmak zorundadır. Burada önemli olan sistemin hangi programlama diliyle geliştirileceği değil, sistem için gerekli olan modelin oluşturulabilmesidir. Sonraki aşamada programlama dili seçimi, ekibin bilgi birikimi, kurumun yatırım ve deneyimleri, sistemin kullanılacağı kişi ve kişilerin özel gereksinimlerine göre yapılmaktadır.
Tasarım yapısının ayrılabilir, birleştirilebilir, anlaşılabilir ve korunabilir olması gerekmektedir. Ayrılabilirlik, anlamlı parçalara ayrılabilmesini ifade etmektedir. Bir problemin alt problemlere bölünebilmesi tasarımın ayrıştırılabilmesiyle mümkün olmaktadır. Birleştirilebilir olması, sınıfı temsil eden parçanın başka tasarımlarda da tekrar tekrar kullanılabilmesi yani diğer parçalarla birleştirilebilmesi anlamını taşımaktadır. Tasarımın anlaşılabilirliği, bir sınıfın diğer sınıflarla bilgiye gerek duymadan anlaşılabilmesi ve aynı zamanda yapılacak küçük değişikliklerin etkilerinin en az sayıda sınıfa yayılarak uyarlanmasını ifade etmektedir. Korunabilirlik ise, olası hatalara karşı düzeltilebilmesine yönelik etkilerin geniş bir alana yayılmadan önlenebilmesidir.
Nesneye yönelik tasarım ilkelerini kısaca şu şekilde sıralamak mümkündür:
- Düşük Bağlılık (Low Coupling)
- Yüksek Uyum (High Cohesion)
Düşük bağlılık: Bir sınıfın diğer sınıflarla bağlılık oranı olarak düşünülebilir. Düşük bağlılığın en önemli faydası bir sınıfta yapılan değişikliğin diğer sınıfların az etkilenerek uyarlanmasının sağlanmasıyla birlikte yeniden kullanılabilirliğin artması olarak söylenebilir.
Yüksek uyum: Burada bahsedilen uyum aslında bir sınıfın sorumluluklarının birbirleriyle uyumlu olma oranı olarak düşünülmektedir. Uyum, modüllerin veya sınıfların birbirine olan benzerliği yani aynı amaca hizmet eden kod bloklarının bulunması anlamını taşımaktadır.
Nesneye Yönelik Programlama Temelleri
Nesneye yönelik programlama, geliştirilen yazılım üzerinde bakım (maintenance), genişletilebilirlik (extensibility) ve kodun yeniden kullanılabilirliği (reusability) sağlamaktadır.
Yazılımın bakımı, ya mevcut sınıflarda değişiklik ya da yeni sınıf eklenmesi anlamına gelmektedir. Bu da yazılımın tamamını hiçbir şekilde etkilememekte, dolayısıyla bakım kolaylığı getirmektedir.
Genişletilebilirlik; mevcut bir sınıfa yeni özellik veya yapılar ekleyerek artan işlevsellik sağlanmasıdır.
Kodun yeniden kullanılabilmesi; üretilen sınıfların her uygulama geliştiricinin kullanımına açık olan bir ortak kütüphanede tutulmasına imkân sağlamasıdır.
Nesneye yönelik programlama yaklaşımının üç temel ilkesi vardır. Bunlar:
- Sarmalama (Encapsulation)
- Kalıtım (Inheritance)
- Çok biçimlilik (Polymorphism)
Sarmalama yazılan kodun değiştirebilirliğini sağlamaktadır. Nesneye yönelik programlama içerisinde, bir sınıf içerisindeki nitelikler, programın çalışması sırasında nesnelerin anlamlı ve tutarlı durumlarını oluşturmaktadır. Nesne ilk oluşturulduğu anda nesnenin ilk durumunu anlamlı kılabilmek için “Kurucular (Constructors)” ismiyle adlandırılan metotlar kullanılmaktadır. Nesneye yönelik programlama yaklaşımı içerisinde bazı özellikler ve metotlar sadece dışarıdan kullanılmak üzere hazırlanmaktadır. Buna karşılık bazı özellikler ve metotlar ise diğerlerine yardımcı olmak, sadece sınıfın iç işlerinde kullanılmak için yazılmaktadırlar. Bazı durumlarda güvenlik ve sağlamlık amacıyla bir sınıfta kullanılan özelliklerin değiştirmesi ve bazı metotlara erişmesi engellenmek istenilebilir. Bu durumlar için erişim sınırlandırma işlemine sarmalama (encapsulation) adı verilmektedir.
Kalıtım yapısı, birtakım özelliklerin miras alınabilmesi anlamındadır. Yani, bir sınıfın başka bir sınıftaki özelliklere ve metotlarına sahip olmasıdır. Bir anlamda kodun yeniden kullanılabilirliğini sağlayan yapıdır. Kalıtımla, bazı durumlarda başka birisinin yazdığı sınıfa bazı eklemeler yaparak belli bir işlem için kullanılır hale getirmek için de kullanılabilmektedir. Bazen de ortak birçok özellik içeren iki sınıfta da bulunan özellikleri ve metotları tanımlamaktan kurtulmak için kullanılabilir. Kalıtım, programlama ortamında da gerçek hayattaki tanımına benzer bir işi gerçekleştirmektedir. Bir sınıfın başka bir sınıftan kalıtım yapması demek, kalıtımı yapan sınıfın diğer sınıftaki nitelik ve metotları kendisine alması demektir. Eğer kalıtımı yapan sınıfa “alt sınıf”, kendisinden kalıtım yapılan sınıfa “ata sınıf” dersek, ata sınıfta tanımlı olan her şeyin alt sınıf için de tanımlı olduğunu söyleyebiliriz. Kalıtım ilişkisi, UML dili içerisinde ↑ sembolü ile ifade edilmektedir ve birden fazla düzeyli olacak şekilde de kurulabilmektedir. Kalıtım hiyerarşisinde yukarıya doğru çıkıldıkça genele, aşağıya doğru inildikçe özele doğru gidilmektedir. UML diyagramlarında kalıtımı belirten ↑ sembolü, kendisinden kalıtan sınıf yönünde izlendiği zaman, genele gidilmektedir. “çoklu kalıtım (multiple inheritance)” kavramı bir sınıfın birden fazla sınıftan bir takım özellik ve miras aldığı durumlardır. Çoklu kalıtım yapısı tasarım açısından biraz daha karmaşıktır. Java’da çoklu kalıtım yapısı dilin kendine has birtakım özellikleriyle, arayüz (interface), soyut sınıf (abstract class) gibi yapılarla uygulanabilmektedir
Çok biçimlilik, nesnelerin içeride farklı çalışmalarına rağmen, dışarıdan aynı biçimde görünmelerini ifade etmektedir. Bu şekilde, bir grup nesneyi kullanan sınıflar kalıtımla ilgili detayları bilmek zorunda kalmamakta, içerideki değişikliklerden etkilenmeden çalışmaya devam etmektedirler. Aynı sınıftan türetilen sınıflar standart bir şekilde erişilebilme özelliklerine sahip olmaktadır. Aslında çok biçimlilik, bir nesnenin bir işlemi farklı şekillerde yapabileceğini göstermektedir. Birbirine benzeyen nesneleri ortak özellikleriyle ele alarak ya da nesnelerin aynı işi farklı şekillerde yapabilmesini sağlamaktadır.