2.DAVRANIŞSAL TASARIM DESENLERi
2.1.Durum ( State ) Tasarım Deseni
Nesnenin durumu değiştiğinde, davranışı da değişiyorsa, yani nesneler farklı durumlarda, farklı davranışlar gösteriyorsa, durum tasarım deseni kullanılabilir. Bu tasarım deseninin kullanılması, nesnelerin durumlarına bağlı değişen davranışlarının karmaşık “if/else” veya “switch” ifadeleriyle kontrol edilmesini önler.
Örnek verelim;
1 2 3 4 5 6 7 8 9 |
package state; /* HesapDurumu.java*/ public interface HesapDurumu { void paraÇek(); void faizÖde(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package state; /*NormalHesap.java*/ public class NormalHesap implements HesapDurumu { @Override public void faizÖde() { System.out.println( "Normal hesaptan faiz ödendi." ); } @Override public void paraÇek() { System.out.println( "Normal hesaptan para çekildi." ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package state; /*AltınHesap.java*/ public class AltınHesap implements HesapDurumu { @Override public void faizÖde() { System.out.println( "Altın hesaptan faiz ödendi." ); } @Override public void paraÇek() { System.out.println( "Altın hesaptan para çekildi." ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package state; /* Hesap.java*/ public class Hesap { private HesapDurumu hesapDurumu; public Hesap() { hesapDurumu = new NormalHesap(); } public void faizÖde() { hesapDurumu.faizÖde(); } public void paraÇek() { hesapDurumu.paraÇek(); } public void durumDeğiştir( final HesapDurumu hesapDurumu ) { this.hesapDurumu = hesapDurumu; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package state; /* Müşteri.java*/ public class Müşteri { public static void main( final String[] args ) { // Yaratılan hesap varsayılan olarak 'normal' durumda. final Hesap hesap = new Hesap(); hesap.faizÖde(); hesap.paraÇek(); // Çalışma zamanında hesap durum değiştiriliyor. // Müşteri altın hesaba geçiriliyor. hesap.durumDeğiştir( new AltınHesap() ); System.out.println( "Müşteri altın hesaba geçiriliyor." ); // Durum değiştiği için davranış da değişecek. hesap.faizÖde(); hesap.paraÇek(); } } |
2.2.Gözlemci ( Observer ) Tasarım Deseni
Bir nesnenin durumlarında değişiklik olduğunda, bu değişikliklerden haberdar olmak isteyen diğer nesnelere haber verilmesi gerektiği durumlarda bu tasarım deseni kullanılır. Bu haber verilme işlemi sırasında, haber verilecek nesnelerin birbirlerine bağımlı olması istenmez. Yani kısaca dinleyici konumunda bulunan bir çok nesne, bir nesnenin durumunu sürekli gözlemler. Bir değişiklik sırasında gözlemcilere haber verilir.
Örnek verelim;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
abstract class ElementBase { public delegate void ElementChange(Element element); public event ElementChange OnElementChange = null; public void Attach(ElementChangeListener listener) { OnElementChange += new ElementChange(listener.Update); } public void Detach(ElementChangeListener listener) { OnElementChange -= new ElementChange(listener.Update); } public void Notify(Element element) { if (OnElementChange != null) { OnElementChange(element); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
class Element: ElementBase { private int _elementId; private string _name; public int ElementId { get { return _elementId; } set { if (_elementId != value) { _elementId = value; Notify(this); } } } public string Name { get { return _name; } set { if (_name != value) { _name = value; Notify(this); } } } } |
1 2 3 4 |
interface IObserver { void Update(Element e); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class ElementChangeListener: IObserver { public void Update(Element element) { Console.WriteLine(@"{0} Id'li element değişmiştir.", element.ElementId); } } static void Main(string[] args) { Element element1 = new Element { ElementId = 1, Name = "Element 1" }; element1.Attach(new ElementChangeListener()); element1.Name = "Element 2"; Console.ReadLine(); } |
2.3.Strateji ( Strategy ) Tasarım Deseni
Bir işlem için farklı yöntemlerin uygulanabilir olduğu durumlarda, bu yöntemi kullanacak olan nesne, hangi yöntemin uygulanacağını seçer. Çünkü bu içerik nesnesi, yöntemleri belirleyen üst sınıfı içerir. Farklı yöntem veya strateji alt sınıfları da, bu üst sınıftan türerler. Bu tasarım deseniyle, yöntemin nasıl uygulanması gerektiği ile ilgili detaylar, bu yöntemi kullanacak nesneden ayrılmış olur. Ayrıca bu tasarım deseninin kullanılmasıyla, kod uzun “if/else” veya “switch” ifadelerinden ayıklanır.
Örnek verelim;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public abstract class Ordek { protected Otebilme otebilme; protected Ucabilme ucabilme; public abstract double puanla(); public abstract void ciz(); public void setOtebilme(Otebilme otOzellik) { otebilme = otOzellik; } public void setUcabilme(Ucabilme ucOzellik) { ucabilme = ucOzellik; } public void uc(){ ucabilme.uc(); } public void ot(){ otebilme.ot(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class YesilOrdek extends Ordek { public YesilOrdek(){ otebilme = new Vakvak(); ucabilme = new KanatlaUc(); } @Override public double puanla() { // TODO Auto-generated method stub return 10.0; } @Override public void ciz() { // TODO Auto-generated method stub System.out.println("Yeşil Ördek"); } } |
1 2 3 4 5 |
public interface Ucabilme { public void uc(); } |
1 2 3 4 5 6 7 8 9 |
public class KanatlaUc implements Ucabilme { @Override public void uc() { // TODO Auto-generated method stub System.out.println("Kanatla Uç"); } } |
1 2 3 4 5 6 7 8 |
public class Ucamama implements Ucabilme { @Override public void uc() { // TODO Auto-generated method stub System.out.println("uçamama"); } } |
1 2 3 4 5 6 |
package uygulama3; public interface Otebilme { public void ot(); } |
1 2 3 4 5 6 7 8 9 |
public class Vikvik implements Otebilme { @Override public void ot() { // TODO Auto-generated method stub System.out.println("Vik Vİk"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class Test { public static void main(String[] args){ Ordek ord = new PlastikOrdek(); ord.ciz(); ord.ot(); ord.setOtebilme(new Vakvak()); ord.ot(); YesilOrdek ord2 = new YesilOrdek(); ord2.ciz(); ord2.ot(); ord2.uc(); ord2.setUcabilme(new Ucamama()); ord2.setOtebilme(new Suskun()); ord2.ot(); ord2.uc(); } } |
2.4.Tekrarlayıcı (Iterator) Tasarım Deseni
Tekrarlayıcı tasarım kalıbı; birleşik bir nesnenin bileşenlerine, nesnenin esas ifadesinin gösterilimini açığa çıkarmadan sırayla erişebilmeyi sağlar. Kullanıldığı Durumlar
Tekrarlayıcı tasarım kalıbı, bir listenin yapısının ve çalışma tarzının uygulamanın diğer kısımları ile olan bağlantılarını en aza indirmek için; listede yer alan nesnelerin, sırasıyla uygulamadan soyutlanması amacıyla kullanılır.
Tekrarlayıcı kalıbın içinde yer alan yapılar aşağıdaki gibi sıralanır:
Tekrarlayıcı (Iterator): Öğelere ulaşmak ve öğeleri çaprazlamak için bir arabirim tanımlar.
Somut Tekrarlayıcı (Concrete Iterator): Tekrarlayıcı arayüzünü sağlar.
Birleşik (Aggregate): Tekrarlayıcı nesnelerin yaratılması için bir arabirim oluşturur.
Somut Birleşik (Concrete Aggregate): Uygun somut tekrarlayıcı aşamasına dönmek için tekrarlayıcı arabiriminin oluşturulmasını sağlar. Bu yapısal kod; koleksiyonun esas yapısını detaylandırmaksızın, nesne koleksiyonlarını tekrarlanmasını sağlayan tekrarlayıcı tasarım kalıbı örnekle gösterilebilir.
1.Adım:
1 2 3 4 |
public interface Iterator { public boolean hasNext(); public Object next(); } |
1 2 3 |
public interface Container { public Iterator getIterator(); } |
2. Adım:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class NameRepository implements Container { public String names[] = {"Robert" , "John" ,"Julie" , "Lora"}; @Override public Iterator getIterator() { return new NameIterator(); } private class NameIterator implements Iterator { int index; @Override public boolean hasNext() { if(index < names.length){ return true; } return false; } @Override public Object next() { if(this.hasNext()){ return names[index++]; } return null; } } } |
3.Adım:
1 2 3 4 5 6 7 8 9 10 11 |
public class IteratorPatternDemo { public static void main(String[] args) { NameRepository namesRepository = new NameRepository(); for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){ String name = (String)iter.next(); System.out.println("Name : " + name); } } } |
4.Adım:
1 2 3 4 |
Name : Robert Name : John Name : Julie Name : Lora |
2.5.Chain Of Responsibility
Bir isteğin belli sınıflar içinde gezdirilerek ilgili sınıfın işlem yapmasını yönetir.
2.6.Commandİşlemlerin nesne haline getirilip başka bir nesne(invoker) üzerinden tetiklendiği bir tasarım desenidir.
2.7.Interpreter
İşlemlerin nesne haline getirilip başka bir nesne(invoker) üzerinden tetiklendiği bir tasarım desenidir.
2.8.Mediator
Çalışmaları birbirleri ile aynı arayüzden türeyen nesnelerin durumlarına bağlı olan nesnelerin davranışlarını düzenler.
2.9.Memento
Bir nesnenin tamamının veya bazı özelliklerinin tutularak sonradan tekrar elde edilmesini sağlar.
2.10.Template method
Bir algoritmanın adımlarının abstract sınıfta tanımlanarak farklı adımların concrete sınıflarında overwrite edilip çalıştırılmasını düzenler.
2.11.Visitor
Uygulamada ki sınıflara yeni metotlar eklenmesini düzenler.
Yazının devamı için bkz.
Resimlerin kalitesi keşke daha iyi olsaydı.
odana tablo olarak mı asacaksın. :)))))))))))))))))))))))))))))))))))))))))))))))))))
Bu yüzden ülkemiz gelişmiyor işte 🙂