TASARIM KALIPLARI-DEVAM Singleton Adapter 1
Singleton (Yegane/Tekil) Tasarım Kalıbı Singleton tasarım kalıbı; bir sistem içerisinde yalnızca bir nesne üretilerek bu nesnenin kullanılması gerektiği durumlarda kullanılır. 2
Singleton Tasarım Kalıbı Singleton tasarım kalıbı bir uygulamanın yaşamı süresince belirli bir nesneden sadece bir örneğin olmasını garanti altına alır. Eğer nesne yaratılmışsa, bu kalıp sayesinde yeni bir yaratma işlemi yerine yaratılan nesnenin referansı işaret edilir. 3
Singleton Tasarım Kalıbı Ayrıca bu kalıp, yaratılan tek nesneye, ilgili sınıfın dışından global düzeyde erişilmesini hedefler. Singleton kalıbında istenilen; yalnızca bir nesnenin yaratılması olduğundan, ilgili sınıfın içinde bir yerde nesnenin oluşturulması gerekir. 4
Singleton Tasarım Kalıbı Bu da static bir özellik ya da static bir metot ile mümkündür. Bu static metot, sınıfın kendi içinde yaratılan nesneyi geri dönüş değeri olarak dönecektir. Bu nesne, static metodun ya da özelliğin içinde yaratılıp, yine sınıfın private olan elemanına atanır. Tekil olarak yaratılan bu nesneye erişmek için bu private olan elemanın referansına geri dönmek yeterli olacaktır. 5
Singleton Tasarım Kalıbı 6
Singleton Tasarım Kalıbı 7
Singleton Tasarım Kalıbı Uygulamalardan Örnekler; bir muhasebe sisteminde ay sonu hesap kesimini yapan sınıf, kredi kartı ile ödeme yapılan bir sistemdeki kredi kartı para çekme işlemini yapan sınıf, uçak iniş kalkışlarının ayarlandığı uçuş yönetimini sağlayan sınıf sistemde sadece bir tane olması gereken sınıflardır. Singleton kalıbı ile bu koşul garanti altına alınmış olur. 8
Singleton Tasarım Kalıbı Uygulama Adımları Uygulamada global bir nesneye(instance) ihtiyaç vardır. Bu nesne her yerden erişilebilir olmalı, fakat sadece bir kez yaratılmalıdır. Uygulamanın tüm parçalarının aynı instance ı kullanması istenir. 9
Singleton Tasarım Kalıbı Uygulama Adımları Bunu başarabilmek için, ana uygulamada global bir nesne yaratılması ve sonrasında bu nesnenin referansının ihtiyaç olduğunda geçirilmesini sağlanmalıdır. 10
Singleton Tasarım Kalıbı Uygulama Adımları Global değerlerin yaratılması için bir diğer yol ise static değişkenler kullanmaktır. Nesne yaratma üzerindeki kontrolden emin olmak için kurucu metot private olarak tanımlanmalıdır. 11
Singleton Tasarım Kalıbı Bu bir sorunu taşır: bir instance yaratılması imkansız olur. Bundan dolayı erişimci/aracı bir metot (getinstance()) static bir metot tarafından sağlanmaktadır. 12
Singleton Tasarım Kalıbı Bu metot önceden yaratılmadıysa, yeni tek bir instance yaratır ve singleton un referansını, bu nesneyi çağıran fonksiyona döndürür. 13
Singleton Tasarım Kalıbı Singleton un referansı gelecek istekler içinsınıfında tanımlananan static bir property de saklanır. 14
Singleton yapıya sahip bir sınıf: /*Singleton tasarim sablonu örnegi @author Özcan Acar */ public class Singleton { /*Singleton sınıfından oluşturulabilecek tek nesne static sınıf değişkeni olarak tanımlanıyor. */ private static Singleton instance = null; /*Double check locking yapabilmek için kullanılan nesne*/ private static Object lock = new Object(); 15
Singleton yapıya sahip bir sınıf-devam /* Başka sınıfların new Singleton() şeklinde nesne oluşturmalarını, sınıf kurucusunu(constructor) private yaparak engellemiş oluyoruz.*/ private Singleton() { System.out.println("singletion init()"); } 16
Singleton yapıya sahip bir sınıf-devam /* Singleton sınıfından oluşturulabilen tek nesneye ulaşmak için instance() metodu kullanılır.*/ public static Singleton instance() { if(instance == null) { // Double checked locking synchronized (lock) { if(instance == null) {instance = new Singleton();}} } return instance;} 17
Singleton yapıya sahip bir sınıf-devam /*Singleton sınıfında bulunan bir metod*/ public void printthis() { System.out.println(this); } } 18
Singleton yapıya sahip bir sınıf-devam SORU: multi threaded bir java uygulaması için; public static Singleton instance() Metodunun yukarıdaki içeriği yeterli olur mu? Neden? Nasıl olmalıdır? Araştırınız. 19
Bir singleton sınıfın taşıması gereken bazı özellikler : Sınıf kurucularının (constructor) private olması gerekiyor. Kurucuları private olan bir sınıftan, başka bir sınıf new operatörü ile nesne oluşturamaz. 20
Bir singleton sınıfın taşıması gereken bazı özellikler : Singleton sınıfından sadece bir tane nesne oluşturulması gerektiği için, oluşturulması gereken nesneyi sınıfın static değişkeni olarak tanımlamamız gerekiyor. Yukardaki örnekte private static Singleton instance = null; şeklinde bu tanımlamayı yapıyoruz. 21
Bir Singleton sınıfın taşıması gereken bazı özellikler : Singleton sınıfında instance() isminde static bir metodun olması ve bu metodun static olarak tanımlanmış nesneyi geri vermesi gerekiyor. instance() metodu içinde sınıfın tek nesnesi olacak değişken oluşturulur. 22
Örnek: SingleObject Kurucu(constructor) metodu private tanımlanmış böylece kendisinden nesne yaratılmasını engelleyen bir SingleObject sınıfı yaratınız. Bu sınıfa static bir metot olan ve istenildiğinde sınıfın instance ını geriye döndüren bir getinstance() metodunu yaratınız. 23
Singleton Program sınıfında getinstance() metodu ile birden fazla SingleObject nesnesi yaratınız. 24
Singleton SingleObject.java 25
Program.java Singleton Program çıktısı: 26
Artıları ve Eksileri-I Singleton kendi kendinin instance ını yaratabilen tek sınıftır. Sağlanan static metodu kullanmadan yeni bir singleton yaratılamaz böylece yaratılan nesne programın çalışma süresince o sınıfın tek nesnesi olur. 27
Artıları ve Eksileri-II Singleton a ihtiyaç duyan nesnelerin tümüne aynı singleton un referansını geçirilmesi gerekmez; çünkü o sınıfa her erişildiğinde aynı singleton nesnesinin referansını geri döndürür. Fakat, Singleton tasarım kalıbı implementasyona bağlı olarak, threading sorunları çıkarabilir. Bir multi threading uygulamada singleton un başlatılma şekline dikkat edilmelidir. Uygun olmayan bir kontrolle, uygulamanız bir thread savaşları na sahne olacaktır. 28
Structural(Yapısal) Kalıplar Yapısal tasarım kalıpları, farklı sınıfların ve nesnelerin daha büyük yapılar oluşturulması için nasıl birleştirileceğine dair bir taslak sunar. 29
Structural(Yapısal) Kalıplar Çoğunlukla aynı temel amaç için farklı yolların kullanıldığı Creational kalıpların aksine, her bir yapısal kalıp farklı bir amaca sahiptir. 30
Structural(Yapısal) Kalıplar Yapısal kalıpların tümü, nesnelerin arasındaki bağlantıları geliştirir. Bir anlamda da, veri yapıları kavramının basit haline benzemektedirler. Fakat, sadece aralarındaki referansları değil nesneleri birbirine bağlayan metotları da özelleştirmektedirler. 31
Structural(Yapısal) Kalıplar Yapısal tasarım kalıpları bileşenlerin veya modüllerin yapı içerisinde nasıl düzene gireceklerini açıklarlar. Yapısal tasarım kalıpları ayrıca kalıp boyunca verinin nasıl hareket edeceğini de açıklar. 32
Structural(Yapısal) Kalıplar Bu tasarım kalıbı kategorisinde, modüller yada bileşenler arasındaki kompozisyonun nasıl olması gerektiği tartışılır. Yapısal tasarım kalıpları, sistemin esnek olabilmesi için bileşenlerin nasıl yapılandırılması gerektiğini tanımlarlar. 33
Adapter 34
Adapter 35
Adapter Nesneye yönelik programlamanın sıklıkla sözü geçen avantajlarından birisi de kodun yeniden kullanabilir olmasını sağlamasıdır. Verilerin ve davranışların bir sınıf merkezinde toplandığı bir sınıfın başka bir projeye aktarılması sonrası sınıfın fonksiyonelliği çok az bir maliyetle kullanılabilinmektedir. 36
Adapter Maalesef, biz geliştiricilerin geleceği tahmin etme yeteneği bir şekilde sınırlıdır. Bir projenin gelecekteki kodlama gereksinimlerinin ne olacağını bilmediğimizden dolayı her zaman yeniden kullanılabilir bir sınıfın tasarımının nasıl olması gerektiğini bilemeyiz. 37
Adapter Geliştirilen bir uygulama için yabancı bir iş ortağı ile işbirliği yapmaya karar verdiğinizi varsayalım. İş ortağınız benzer bir projede çalışmakta ve size ticari uygulamanın bir bileşeni olan adres sistemini sağlayabilmektedir. 38
Adapter Fakat siz bu dosyaları aldığınızda, projenizde kullandığınız ara yüzler ile dosyadaki ara yüzlerin eşleşmediğini farkettiniz. Daha da kötü bir senaryo ise kod İngilizce değil, arkadaşınızın ana dilinde yazılmış. Böyle bir durumda kendinizi iki kötü çözümle karşı karşıya bulursunuz. 39
Adapter İlk seçeneğiniz bileşenin yeniden yazılması ve böylece gereken tüm arayüzleri implemente edilmesidir. Bileşeni baştan yazmak kötü bir fikirdir. Çünkü arkadaşınızdan bileşenin her yeni bir sürümünü size ilettiğinde bileşeni yeniden yazmanız gerekecektir. 40
Adapter İkinci bir seçenek ise uygulamanızı yeniden yazmak ve arkadaşınızın sağladığı bileşene uygun bir şekilde tasarlamaktır. Buradaki olumsuzluk ise, eski ara yüzdeki herhangi bir değişiklik esnasında tüm kodu değiştirmek zorunda kalmanız ve kodunuzun anlaşılması daha da zor olmasıdır. Çünkü siz iş ortağınızın dilini bilmiyorsunuz. 41
Adapter 42
Adapter Adlandırmalar ne kadar doğru olsa bile, sizin için hiçbir anlam ifade etmeyecektir. Burada ihtiyacınız olan şey ise bir tercümandır. İşte bu da tam olarak Adapter tasarım kalıbının yaptığıdır. 43
Adapter 44
Adapter Bir güç adaptörüne benzer şekilde davranarak, bir tipi bir diğer uyumsuz-tipe dönüştürür. 45
Adapter tasarım kalıbı Temelde birbiriyle uyumsuz ancak aynı işi yapması öngörülen iki interface'in haberleştirilmesi için kullanılır. Adapter tasarım kalıbının kullanımı, sizin uygulamalarınızın yeni bileşenlerin kullanımına izin verdiği gibi aynı zamanda sizin var olan ara yüzlerinizi kullanmaya devam etmenize olanak sağlar. 46
Adapter tasarım kalıbı Yeni bir sürüm geldiğinde, yapmanız gereken sadece Adapter i değiştirmektir. 47
Adapter tasarım kalıbı Adapter Tasarım Kalıbı Sınıf Diyagramı 48
Adapter tasarım kalıbı Framework: Adapter i kullanan yapı. Adapter: Framework un kullanacağı metotları tanımlayan arayüz. Adaptee: Adapte edilecek tipin metotlarını tanımlayan ara yüz. Bu arayüz, çalışma zamanında dinamik olarak belirli Adaptee nin yüklenmesine izin verir. 49
Örnek: Medya Oynatıcısı Adapter tasarım kalıbını;.mp3 uzantılı dosyaları çalabilen sıradan bir medya oynatıcısını,.mp4 ve.vlc formatını çalabilen bir medya oynatıcısına dönüştürürken kullanacağız. 50
Örnek: Medya Oynatıcısı IMedyaOynatabilen arayüzüne ve somut(concrete) bir sınıf olan ve IMedyaOynatabilen ara yüzünü implemente eden bir MedyaOynaticisi sınıfımız var. MedyaOynaticisi varsayılan olarak.mp3 uzantılı dosyaları çalabilmektedir. 51
Örnek: Medya Oynatıcısı IMedyaOynatabilen.java 52
Örnek: Medya Oynatıcısı MedyaOynaticisi.java 53
Örnek: Medya Oynatıcısı Program.java 54
Örnek: Medya Oynatıcısı Biz diğer IModernMedyaOynatabilen arayüzüne ve bu arayüzü implemente eden somut sınıflara sahibiz. Bu sınıflar ayrı ayrı.vlc ve.mp4 oynatabilmektedir. Biz MedyaOynaticisi nin diğer uzantıları da oynatmasını istiyoruz. Bunu yapabilmek için bir adapter sınıfına ihtiyaç duyarız. 55
Örnek: Medya Oynatıcısı MedyaOynaticisi sınıfı adapter sınıf olan MedyaAdapter sınıfını kullanarak istenilen medya tipini (bu medya tipini hangi sınıfın kullanabileceğini bilmeden )geçirmektedir. Program sınıfı ise çeşitli uzantıları çalmak MedyaOynaticisi ni kullanan bir sınıftır. 56
Örnek: Medya Oynatıcısı-devam 1.IMedyaOynatabilen ve IModernMedyaOynatabilen ara yüzlerini yaratırız. IMedyaOynatabilen.java 57
Örnek: Medya Oynatıcısı-devam IModernMedyaOynatabilen.java 58
Örnek: Medya Oynatıcısı-devam 2.IModernMedyaOynatabilen arayüzünü implemente eden VlcOynaticisi ve Mp4Oynaticisi somut sınıflarını yaratırız. VlcOynaticisi.java 59
Örnek: Medya Oynatıcısı-devam 2.IModernMedyaOynatabilen arayüzünü implemente eden VlcOynaticisi ve Mp4Oynaticisi somut sınıflarını yaratırız. Mp4Oynaticisi.java 60
Örnek: Medya Oynatıcısı-devam 3. IMedyaOynatabilen arayüzünü implemente eden MedyaAdapter sınıfını yaratırız. Bu sınıfa geçirilen medyanın uzantısına bağlı olarak IModernMedyaOynaticisi ara yüzü nesneleri yaratırız. 61
Örnek: Medya Oynatıcısı-devam MedyaAdapter.java 62
Örnek: Medya Oynatıcısı-devam 4.IMedyaOynatabilen ara yüzünü implemente eden MedyaOynaticisi somut sınıfını yaratırız. 63
Örnek: Medya Oynatıcısı-devam MedyaOynaticisi.java 64
Örnek: Medya Oynatıcısı-devam 5.Program sınıfında MedyaOynaticisi nesnesi yaratıp çeşitli formattaki medyaları çalabiliriz. Program.java 65
Artıları ve Eksileri-I: Adapter tasarım kalıbı, iki veya daha fazla uyumsuz nesnenin birbirleri ile etkileşim kurmasını sağlayarak yüksek derecede yeniden kullanılabilirlik sunar. 66
Artıları ve Eksileri-II: Fakat uygun biçimde adaptif ve yeteri kadar esnek bir yapı kurabilmek için biraz planlama ve önsezi gerekmektedir. Bu problemin iki yönü vardır: Fonksiyonların çağrılarının doğru kurgulanması. Aktarılan parametrelerin çevrilmesi. 67
Artıları ve Eksileri-III: Yapı(framework) ile Adaptee arasındaki yanlış bir fonksiyonel eşleşme olduğunda; Adapter, Adaptee nin istediği gereksinimleri yönetmesi, framework un çağrısından önce gerekli düzenlemeleri yapması gerekir. 68
Artıları ve Eksileri-IV: Adapter için bir diğer zorluk ise parametrelerin taşınmasıdır, bazen geçirilen parametreler framework ile Adaptee arasında kullanılmak için uygun olmayabilir. Bu gibi durumlarda, Adapter genellikle iki ortam arasında doğrudan bir ilişki bulunmadığında uygun iki nesneyi de yaratır yada Adaptee tarafından kullanılabilir olması için sarmalayıcı bir nesne (wrap) yaratır. Adapter tasarım kalıbının bir diğer bilinen adı ise wrapper dır. 69
KAYNAKLAR: Aykut Taşdelen, C++, Java ve C# ile UML ve Dizayn Paternleri, Pusula Yayıncılık, İstanbul, 2014 Eric Freeman, Head First Design Patterns, O'Reilly Media, 2004 Stephen Stelting& Olav Maassen, Applied Java Patterns, Prentice Hall PTR, 2001 http://www.algoritmaveprogramlama.com http://www.tutorialspoint.com/ http://www.kurumsaljava.com/ http://bidb.itu.edu.tr/seyirdefteri/ 70