YZM311 YAZILIM YAPIMI BÖLÜM 4 TASARIM KALIPLARI Yrd. Doç. Dr. Volkan TUNALI Mühendislik ve Doğa Bilimleri Fakültesi / Maltepe Üniversitesi
Giriş 2 Tasarım Kalıpları (Design Patterns) Yaratımsal (Creational) Kalıplar Singleton Factory Method Yapısal (Structural) Kalıplar Adapter Decorator Davranışsal (Behavioral) Kalıplar Strategy Command
Tasarım Kalıpları 3 Yazılım Mühendisliğinde Tasarım Kalıpları, yazılım tasarımında sıklıkla karşılaşılan problemler için genel ve tekrarlanabilir çözümlerdir. Bir tasarım kalıbı doğrudan koda çevrilebilecek, tamamlanmış bir tasarım değildir. Tasarım kalıbı, bir tasarım probleminin nasıl çözülebileceğine dair bir açıklama ya da şablon niteliğindedir.
Tasarım Kalıpları 4 Tasarımda yeniden kullanımı (reuse) destekler. Etkinliği kanıtlanmış kalıplara dayalı tasarlanan yazılım sistemlerine olan güveni arttırır. Tasarımcıların yazılım tasarımına ilişkin konularda iyi bilinen ve üzerinde uzlaşılmış isimler kullanarak iletişim kurabilmeleri için ortak bir dil ve kelime dağarcığı sağlar.
Tasarım Kalıpları 5 Yaratımsal (Creational) Kalıplar Nesne yaratım süreciyle ilgili kalıplardır (class instantiation). Yapısal (Structural) Kalıplar Temel olarak sınıfların ve nesnelerin statik bileşimi ve yapısıyla ilgilenen kalıplardır (static composition & structure). Nesnelerin yeni işlevsellikler kazanmaları için birtakım yöntemler sağlarlar. Davranışsal (Behavioral) Kalıplar Sınıflar ve nesneler arasındaki dinamik etkileşim ve iletişimle ilgilidirler (dynamic interaction & communication).
6 Tasarım Kalıpları
Yaratımsal (Creational) Kalıplar 7 Abstract Factory Builder Factory Method Object Pool Prototype Singleton
Yapısal (Structural) Kalıplar 8 Adapter Bridge Composite Decorator Façade Flyweight Private Class Data Proxy
Davranışsal (Behavioral) Kalıplar 9 Chain of Responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State Strategy Template Method Visitor
Singleton Katalog Bilgisi 10 Kategori Yaratımsal (Creational) Amaç Bir sınıfın yalnızca tek bir örneğinin (instance) olmasını ve bu örneğe global bir erişim noktası oluşturulmasını sağlamak. just-in-time initialization veya initialization on first use kavramlarını gerçekleştirmek. Uygulanabilirlik Bir sınıfın yalnızca bir örneğinin yaratılabilmesinin gerekli olduğu uygulamalar. Ayrıca, lazy initialization (geç ilklendirme) ve global erişimin gerekli olduğu yerler.
11 Singleton Yapı
Singleton Kod 12 class Singleton { private static Singleton instance; // Note: Constructor is 'protected' protected Singleton() { public static Singleton Instance() { // Use 'Lazy initialization' if (instance == null) { instance = new Singleton(); return instance;
Factory Method Katalog Bilgisi 13 Kategori Yaratımsal (Creational) Amaç Nesne yaratımı için bir arabirim tanımlamak, ancak hangi sınıftan nesne yaratılacağına alt sınıfların karar vermesini sağlamak. Sanal (virtual) bir yapıcı (constructor) tanımlamak. new operatörü zararlı kabul edilir. Uygulanabilirlik Bir sınıf, yaratması gereken nesnelerin sınıflarını belirleyemez durumdaysa. Bir sınıfın, yaratacağı nesnelerin belirlenmesini alt sınıflarına ertelemesi gerektiğinde.
14 Factory Method Yapı
Factory Method Kod 1/2 15 static void Main() { // An array of creators Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // Iterate over creators and create products foreach(creator creator in creators) { Product product = creator.factorymethod(); Console.WriteLine("Created {0", product.gettype().name);
Factory Method Kod 2/2 16 // "Product" abstract class Product { // "ConcreteProductA" class ConcreteProductA : Product { // "ConcreteProductB" class ConcreteProductB : Product { // "Creator" abstract class Creator { public abstract Product FactoryMethod(); // "ConcreteCreator" class ConcreteCreatorA : Creator { public override Product FactoryMethod() { return new ConcreteProductA(); // "ConcreteCreator" class ConcreteCreatorB : Creator { public override Product FactoryMethod() { return new ConcreteProductB();
Adapter Katalog Bilgisi 17 Kategori Amaç Yapısal (Structural) Bir sınıfın arabirimini istemcinin (client) beklediği başka bir arabirime dönüştürmek. Adapter, uyumsuz arabirimler nedeniyle birlikte çalışamayacak sınıfların birlikte çalışabilmesine olanak sağlar. Mevcut bir sınıfı yeni bir arabirimle sarmalamak (wrap). Eski bir bileşeni yeni bir sistemle uyumlu hale getirmek. Uygulanabilirlik Mevcut bir bileşenin sunduğu cazip işlevsellik nedeniyle kullanılmak istendiği ancak bu bileşenin dünya görüşünün geliştirilmekte olan sistemin mimarisiyle ve felsefesiyle uyumlu olmaması durumunda.
18 Adapter Yapı
19 Adapter Sequence Diagram
Adapter Kod 20 Bu tasarım kalıbı için örnek kodu sınıfta yazalım.
Decorator Katalog Bilgisi 21 Kategori Yapısal (Structural) Amaç Bir nesneye dinamik olarak ek sorumluluklar eklemek. Decorator, bir sınıfın işlevselliği genişletmek için alt sınıflar türetmeye oldukça esnek bir alternatif sunar. Hediyeyi paketlemek, bir kutuya koymak, ve kutuyu paketlemek. Uygulanabilirlik İstenilen nesnelere çalışma zamanında bir durum ya da davranış eklenmek istendiğinde (aynı sınıftaki diğer nesneleri etkilemeden). Statik olması ve tüm sınıfı ilgilendirmesi nedeniyle kalıtımla alt sınıf türetmenin uygun olmadığı durumlarda (boş yere aşırı sayıda alt sınıf kombinasyonu türetmek gerekeceği için).
22 Decorator Yapı
Decorator Kod 1/4 23 1. Create a lowest common denominator that makes classes interchangeable 2. Create a second level base class for optional functionality 3. Core class and Decorator class declare an isa relationship 4. Decorator class hasa instance of the lowest common denominator 5. Decorator class delegates to the hasa object 6. Create a Decorator derived class for each optional embellishment 7. Decorator derived classes delegate to base class AND add extra stuf 8. Client has the responsibility to compose desired configurations
Decorator Kod 2/4 24 // 1. "lowest common denominator" interface Widget { void draw(); // 3. "Core" class with "is a" relationship class TextField implements Widget { private int width, height; public TextField( int w, int h ) { width = w; height = h; public void draw() { System.out.println( "TextField: " + width + ", " + height );
Decorator Kod 3/4 25 // 2. Second level base class with "isa" relationship abstract class Decorator implements Widget { private Widget wid; // 4. "has a" relationship public Decorator( Widget w ) { wid = w; // 5. Delegation public void draw() { wid.draw(); // 6. Optional embellishment class BorderDecorator extends Decorator { public BorderDecorator( Widget w ) { super( w ); public void draw() { super.draw(); // 7. Delegate to base class and add extra stuff System.out.println(" BorderDecorator");
Decorator Kod 4/4 26 // 6. Optional embellishment class ScrollDecorator extends Decorator { public ScrollDecorator( Widget w ) { super( w ); public void draw() { super.draw(); // 7. Delegate to base class and add extra stuff System.out.println( " ScrollDecorator" ); public static void main( String[] args ) { // 8. Client has the responsibility to compose desired configurations Widget awidget = new BorderDecorator( new BorderDecorator( new ScrollDecorator( new TextField( 80, 24 )))); awidget.draw();
Decorator 27 Java I/O framework ü Decorator kalıbına çok güzel bir örnektir. Temel byte-tabanlı I/O yetenekleri InputStream & OutputStream sınıflarıyla sağlanmaktadır. Çeşitli karakter-tabanlı okuma & yazma yetenekleri aynı framework içindeki decorator sınıflarca sağlanmaktadır: InputStreamReader/Writer FileReader/Writer BufferedReader/Writer BufferedReader rdr = new BufferedReader( new InputStreamReader( new FileInputStream(fileName)))
Strategy Katalog Bilgisi 28 Kategori Davranışsal (Behavioral) Amaç Birbirinin yerine kullanılabilecek algoritmalardan oluşan bir algoritma ailesi tanımlamak ve her bir algoritmayı enkapsüle etmek. Strategy sayesinde algoritmaların onları kullanan istemciden (client) bağımsız olarak değişebilmesi sağlanır. Soyutlamayı bir arabirimde yakalamak ve implementasyon detaylarını türetilmiş sınıflara saklamak. Uygulanabilirlik Algoritmanın sıklıkla değiştirilebilir olmasını sağlar ve aynı zamanda alt sınıf türetmeye iyi bir alternatiftir.
29 Strategy Yapı
Strategy Kod 1/3 30 static void Main() { // Context following different strategies SortedList studentrecords = new SortedList(); studentrecords.add("samual"); studentrecords.add("sandra"); studentrecords.add("anna"); studentrecords.add("jimmy"); studentrecords.add("vivek"); studentrecords.setsortstrategy(new QuickSort()); studentrecords.sort(); studentrecords.setsortstrategy(new ShellSort()); studentrecords.sort(); studentrecords.setsortstrategy(new MergeSort()); studentrecords.sort();
Strategy Kod 2/3 31 abstract class SortStrategy { public abstract void Sort(List<string> list); class QuickSort : SortStrategy { public override void Sort(List<string> list) { list.sort(); // Default is Quicksort Console.WriteLine("QuickSorted list "); class ShellSort : SortStrategy { public override void Sort(List<string> list) { //list.shellsort(); not-implemented Console.WriteLine("ShellSorted list ");
Strategy Kod 3/3 32 class MergeSort : SortStrategy { public override void Sort(List<string> list) { //list.mergesort(); not-implemented Console.WriteLine("MergeSorted list "); class SortedList { private List<string> _list = new List<string>(); private SortStrategy _sortstrategy; public void SetSortStrategy(SortStrategy sortstrategy) { this._sortstrategy = sortstrategy; public void Add(string name) { _list.add(name); public void Sort() { _sortstrategy.sort(_list);
Command Katalog Bilgisi 33 Kategori Davranışsal (Behavioral) Amaç İstekleri (request) birer nesne olarak enkapsüle etmek ve böylece istemcilerin farklı istekleri parametre olarak kullanabilmesine, sıraya sokmasına ve log lamasına olanak sağlamak. Geri alınabilir (undoable) işlemleri desteklemek. Object-oriented callback oluşturmak. Action olarak da bilinir. Uygulanabilirlik Talep edilen işlemle ilgili ya da talebin alıcısıyla ilgili özel herhangi bir bilgi sahibi olmaya gerek olmak nesnelere istekte bulunabilmenin gerekli olduğu durumlarda.
34 Command Yapı
Command Kod 1/3 35 static void Main() { // Create receiver, command, and invoker Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(); // Set and execute command invoker.setcommand(command); invoker.executecommand();
Command Kod 2/3 36 abstract class Command { protected Receiver receiver; // Constructor public Command(Receiver receiver) { this.receiver = receiver; public abstract void Execute(); class ConcreteCommand : Command { // Constructor public ConcreteCommand(Receiver receiver) : base(receiver) { public override void Execute() { receiver.action();
Command Kod 3/3 37 class Receiver { public void Action() { Console.WriteLine("Called Receiver.Action()"); class Invoker { private Command command; public void SetCommand(Command command) { this.command = command; public void ExecuteCommand() { command.execute();
Özet 38 Tasarım kalıpları, test edilmiş ve kendini ispatlamış geliştirme paradigmaları sunarak yazılım geliştirme sürecinin hızlandırılmasına katkıda bulunabilirler. Etkili yazılım tasarımı, kodlama aşamasına kadar ortaya çıkmayabilecek sorunların da hesaba katılmasını gerektirir. Tasarım kalıplarının kullanılması ileride büyük sorunlara yol açabilecek küçük ama önemli noktaların önlenmesine ve ayrıca bu kalıplara aşina tasarımcı ve programcılar için kod okunabilirliğinin iyileştirilmesine yardımcı olur. Kalıplar sayesinde, yazılım etkileşimi için iyi bilinen ve üzerinde uzlaşılmış isimler kullanılarak, geliştiriciler arasındaki iletişimi arttırmak mümkün olur. Bu bölümde önemli tasarım kalıplarının sadece birkaç tanesine değinilmiştir. Diğer tasarım kalıpları ve daha fazla ayrıntı için Okuma Önerisindeki kaynaklara başvurabilirsiniz.
Okuma Önerisi 39 Design Patterns, Erich Gamma, Richard Helm, Ralph Johnson, & John Vlissides, Addison-Wesley, 1995 Object-Oriented Software Development Using Java, 2 nd Ed., Xiaoping Jia, Addison-Wesley, 2003 http://sourcemaking.com/design_patterns