Java’da Open/Closed

Merhaba TEKNOLTAN.com okurları ; Javada Open/Closed ilkesini anlatmaya çalışacağım ;
Elbette, kırmızı ışıkta geçebilirsiniz, dur işareti olan yollardan da.Bir süpermarket kasasında kuyruğa girmenize de gerek yok aslında. En azından bazılarının bağırmasını ve küfretmesini umursamazsan olmaz. Ancak herkes yaparsa, o halde kaos olur! Ve programlamada da aynen böyledir, sadık kalmanız gereken bazı kurallar vardır. Özellikle meslektaşlarınızla daha büyük bir proje üzerinde çalışırken daha dikkatli olmanız gereken.

Open/Closed Prensibi;

Hiç kule inşaa etmeye çalıştınız mı? Bu kulenin en ortasındaki parçayı hepsini devirmeden değiştirmeye?

Open_Closed_Prinzip

Tamamen karışık değil mi? Ama kulenin en üstüne bir taş veyahut başka bir şey eklemek ise tamamen rahattır. Buda tamamen bir Class yapısı olarak görebiliriz.

Classımıza örneğin yeni bir method eklemek sorunsuz olacaktır lakin değiştirmek kıyametin kopmasina neden olabilir.

Tüm zamanların en iyi metoduyla tüm zamanların en iyi sınıfını yazdığınızı düşünün. Ve işiniz en iyi olduğu için, dünya çapında 2424245235 programcı tarafından kullanıldığını. Ancak aniden, iki parametre yerine üçlü parametre daha iyi olacağını ve yönteminizi buna göre değiştirmek istediğinizi.

Ne olur? 2424245235 Programcı bir hata alır ve sizi en az on yıl boyunca nefret eder. Bunu önlemek için Open / Closed ilkesi vardır, yani sınıflarımızı uzantılar için açık tutmalı, değişiklikler için kapalı tutmalıyız.

Program kodunu yeniden yazmadan genişletme imkânı, nihayetinde nesne tabanlı programlamanın en büyük avantajlarından biridir. Aşağıda tartışacağımız bu tür uzantıların gerçekleştirilmesi için üç kavram mevcuttur.

-)Kalıtım
-)Delegation
-)Bileşim

Kalıtım;

Kalıtımda, bir nesnenin soyut, belirsiz bir tarifi ile başlarız. Bununla ne demek istiyorum? Bir örnek düşünelim bir sanatçı.

Vererbung_Abstraktion

Her sanatçının sahip olduğu mülk var. Örneğin, her sanatçı bir fikir verdikten sonra ayrılan bir aşamaya girer. Hem bir şarkıcı hem de bir dansçı bir sanatçıdır. Bununla birlikte, sahnedeki performanslarının birbirinden açıkça farklı olduğunu kesinlikle kabul ediyoruz. Bir sanatçıyı çoğaltmak zorunda kalmadan bununla nasıl başa çıkacağız?

Çözüm, kalıtsallığın yardımıyla bir şarkıcıya veya bir dansçıya rafine edebileceğimiz, soyut bir sanatçı sınıfıdır. Öyleyse pratik olalım ve soyut bir SanatciSinifi oluşturalım.

public abstract class Sanatci {       
    public String name = null;
    public Sanatcu(String name) { 
        this.name = name; 
    } 
    public void tanitma(){ 
        System.out.println("Benim adim "+name); 
    }
    public abstract void performance();
    public void tebrik(){ 

        System.out.println("Tesekkurler!"); 
    } 
}

Her sanatçının, Nitelik olarak depoladığımız bir adı vardır. Bu niteliği başlatmak için sınıfın yapıcısını kullanırız. Üstelik, iki yöntemle eğliyoruz ve hayal ediyoruz; böylece her bir sanatçının sahip olması gereken beceriler hayata geçirilmelidir. Bu yöntemler dahilinde yalnızca verilen değerler ile ekran çıktısı üretiyoruz.

Sadece dokuzuncu satır ilginç. Burada soyut metodun performansını tanımlıyoruz; Farklı sanatçıların farklılıkları. Soyut yöntemler yalnızca bir yöntem imzasından ibaret olduğundan, bir bagajınız yok, onun sınıfından türetilmiş bir sınıfta uygulamamız gerekiyor.

Şarkıcı sınıfımız ile başlayalım;

public class Sarkici extends Sanatci{
    public Sarkici(String name) {
        super(name);
    } 
    @Override 
    public void performance() { 
        System.out.println("Vazgectim");     
    }           
}

İlk satırda şarkıcımızı üst sınıf sanatçıdan türetmek için extends anahtar kelimesini kullanıyoruz. Her şarkıcı nesnesi, soyut sanatçı sınıfının yöntemlerini ve özniteliklerini içerir. Sanatçı sınıfının name özniteliğini başlatmak için sarkici yapıcısında super anahtar sözcüğünü kullanırız ki bu sınıfı, üst sınıf yapıcı sanatçı (String name) olarak adlandırırız.

Önemli olan beş ila sekizinci satırda olur. Burada, soyut yöntemi üst sınıftan geçersiz kılarak, performance () yönteminin işlevselliğini uygularız.

Benzer şekilde, dansçı için sınıfı uygulayabiliriz.

public class Dansci extends Sanatci{ 
    public Dansci(String name) { 
        super(name); 
    } 
    @Override 
    public void performance() { 
        System.out.println("Kolbasti");           
    }      
}

Tek fark, ekran çıktısı performance () yöntemidir. Dansçımız tabii ki Vazgeçtim Şarkısı değil, daha ziyade bir kolbastı performansıyla performans sergiliyor. Programımızı test edebilmek için, sınıflarımızın işlevlerini düzene sokan ana yöntemle bir sınıf oluşturduk.

public class test {
    public static void main(String[] args){ 
        Sanatci k = new Sarkici("Haktan"); 
        Sanatci k2 = new Dansci("Namik");        
        k.tanitma();
        k.performance(); 
        k.tebrik();            
        k2.tanitma(); 
        k2.performance();
        k2.tebrik();                     
    }
}

Üçüncü ve dörtüncü satırda, öncelikle bir şarkıcı Haktan ve bir dansçı Namik üretiyoruz. Aşağıda, Sarkici örneğinin k ve Danscu örneği k2’nin tüm yöntemlerini çağırıyoruz. Çıktı;

Benim adim Haktan
Vazgectim
Tesekkurler
Benim adım Namik
Kolbasti
Tesekkurler

Üst sınıf sanatçıların yöntemlerine yaklaşırken hem dansçımızın hem de şarkıcımızın performansı, 1, 3, 4 ve 6. satırdaki baskılar birbirinden pek farklı değildir. Bununla birlikte, özellikle, satır iki ve beşinci satırda yer almaktadır. Bu çıktılar Sarkici ve Dansci sınıflarındaki performans metodunun farklı uygulamaları tarafından üretilir. Haktan Vazgectim söylüyor ve Namik bir Kolbasti yapıyor!

Kalıtım;

Java’da devralma durumunda, üst sınıf ile alt sınıf arasında bir ayrım yapılır. Üst sınıf, (üst sınıf veya taban sınıfı) olarak da bilinir ve tipik olarak ortak Attribute ve farklı ancak benzer nesnelerin ve methodlarıb bir özetidir. Alt sınıf, üst sınıfından tüm öznitelikleri ve methodlarını devralır. Dahası, alt sınıf kendi öz nitelikleri ve methodlarıyla genişletilir. Bir burada üst sınıfın alt sınıfının uzmanlaşmasıyla ilgilidir. Java’da miras, anahtar kelime extends aracılığıyla gerçekleşir. Şimdi genel forma bakalım.

Modifikator class AltSinif extends UstSinif {

Modifikator, public, abstract veya diğer erişim düzenleyicileri gibi değerleri kabul edebilir. Burada alt sınıf, bir şey alan sınıf anlamına helir. Ardından, anahtar kelime extends, üst sınıfın kalıtımını tanıtan genişler. Üst sınıf daha sonra hangi sınıfın miras alınacağını belirtir.

Java’da çoklu miras yok. Anahtar kelime final ile sonuçlandırılan sınıflar, alt sınıflardan türetilemez. Üst sınıf alt sınıflarınızı bilmiyor. Tamamen uygulanmayan bir üst sınıf abstract anahtar kelime ile tanımlanır. Bununla birlikte, abstract işaretlenmiş sınıflardan nesne oluşturulamaz. Alt sınıfa abstract bir Üst sınıfın Attribute ve methodları miras olarak gelir. Bu gelen verileri abstract bir method ile uygulanması lazımdır. Eğer böyle olmazsa, alt sınıf mutlaka abstract olarak karakterize edilmelidir.

Alt sınıf, tüm Attributelerin yanı sıra public protected veya none anahtar sözcüğü ile üst sınıflandırılan Methodlarını devralır. Üst sınıfın privatr anahtar kelime ile işaretlenmiş tüm Attributeleri ve Methodları devralınmaz. Üst sınıfın devralınmış Methodları alt sınıfda aşırı yüklenebilir veya üst üste konabilir (üzerine yazılır).

Aşağıdaki kural geçerlidir:

Attribute veya Methid, üst sınıfdan daha ’privat’ olamaz. Alt sınıfda, üst sınıfın Methodları açık olarak da çağrılabilir, onun için “super” anahtar kelimesi vardır.

Şimdi somut bir örneğe geçelim:

class Dede { ... } 
class Baba extends Dede{ ... } 
class Ogul extends Baba { ... } 
// Yukarida listelenen siniflarin bir nesnesi burada olusturulmustur

Object refA = new Dede();
Object refB = new Baba(); 
Object refC = new Ogul(); 
// instanceof operatorunun ciktisi 
System.out.println(""+refA instanceof Dede); 
System.out.println(""+refB instanceof Dede); 
System.out.println(""+refC instanceof Dede);

Bu örnek sadece yukarıda açıklanan gerçekleri göstermek için kullanıldı.

Bir yazılım geliştiricisinin bakış açısından, bu miras daha az mantıklı. Birisi sınıfı bir Kisi olarak yapmak isterdi; dede, baba ve oğul Kisi sınıfının nesneleri olurdu.

Delegation ;

Hepsini yapamayız! Ve bu gerekli değildir! Kendimiz için yapamayacağımız bir işi yapan birini tanıyan birini tanıyorsak yeter.

Ve sınıflarımız için de durum böyle. Bir yumurta koymak için sıfırdan geliştirmek gerekli değildir. Sınıfımızın yapamadığı şeyler var. Delegation kavramının yardımıyla, görevleri bir sınıftan diğerine aktarabiliriz. Delegeler kavramını kullandığı iyi bilinen bir örnek düğmelerdir.

Düğmeleri sadece iki durumu vardır “bastınız” ve “basılı değil” ve ayrıca nesnelerin durumlarını değiştirdiğinizde diğer nesneler ile bunu paylaşabilir.

Elbette sözcük işlemeniz, Mediaplayer’daki Çal düğmesine basarak oluşturduğunuz bir olaya tepki veremez.

Bu nedenle, bir olay meydana geldiğinde hangi nesnelerin bildirilmesi gerektiğini belirtmeliyiz. Ve sözde olay dinleyicisinin görevi budur. Örneğin, mediaplayer’ımızın oynat düğmesinde, fare clicklerinde düğmeyi dinleyen bir dinleyici var. Elbette, oynat düğmesinin bir video veya ses dosyası çalma kapasitesi yok.

Bununla birlikte, bu görevi devralabilecek bir nesneyi dinleyiciye kaydedebiliriz. Oynat düğmesine basar basmaz, dinleyicinin “multimedya dosyasını yorumlama” görevini dinlediği ve multimedya dosyasını çalabilen dinleyicide kayıtlı olan mediaplayer program bölümüne atadığı bir click olayı üretilir.

Evet umarım anlayabilmişsinizdir, Selametle..

Yorum yapın