Tasarım Kalıpları: Proxy (Vekil) – II

Bir önceki yazıda proxy ya da vekil tasarım kalıbını anlatmıştık. Şimdi ele aldığımız ve bu kalıp ile kavramsal olarak çözdüğümüz problemin kodunu verip tartışmaya devam edelim.

Başbakan arayüzü:

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public interface Basbakan {
	
	public void dertDinle(String dert);
	
	public void isBul(String yakinim);

}

 

GerçekBaşbakan sınıfı, Başbakan arayüzünü gerçekleştirmektedir:

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public class GercekBasbakan implements Basbakan {

	@Override
	public void dertDinle(String dert) {
		System.out.println("Basbakan: Dinliyorum.");
	}

	@Override
	public void isBul(String yakinim) {
		System.out.println("Basbakan: Bana boyle isteklerle gelmeyin.");
	}
}

 

VekilBaşbakan sınıfı da Başbakan arayüzünü gerçekleştirmektedir, dahası GerçekBaşbakan sınıfının nesnesini bilmektedir. VekilBaşbakan sınıfının iki temel görevi vardır: İlki, Başbakan olarak görünmek, bunu bu arayüzü gerçekleştirerek elde ediyoruz. Bunun sebebi açıktır, Vatandaş daima Başbakan ile konuşmalıdır. Diğeri ise vekillik yapmak, yani gerekli kontrolleri yaptıktan sonra kendisine gelen istekleri GerçekBaşbakan‘a iletmek. Bu yüzden bu sınıf, GerçekBaşbakan sınıfının nesnesini , nesne değişkeni olarak almıştır ve tipik olarak bu sınıftaki metotlar GerçekBaşbakan‘daki aynı metotlara ulaşır. Bu sınıftaki “isBul()” metoduna baktığınızda göreceksiniz ki iş istekleri GerçekBaşbakan‘a iletilmiyor. Bu durumun sebebi GerçekBaşbakan‘ın “bana iş istekleriyle gelmeyin” demesidir 🙂 .

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public class VekilBasbakan implements Basbakan {
	
	private Basbakan gercekBasbakan = new GercekBasbakan();

	@Override
	public void dertDinle(String dert) {
		System.out.println("Vekil: Derdinizi dinliyorum.");
		
//		if(......)  // Bütün kontroller burada!
		gercekBasbakan.dertDinle(dert);
	}

	@Override
	public void isBul(String yakinim) {
		System.out.println("Vekil: Isteginizi dinliyorum.");
	}
}

 

BaşbakanlıkKalemi sınıfı ise aslen bir factory ayni üretici sınıftır ve üzerinde “banaBasbakaniVer()” metodu çağrıldığında sahip olduğu VekilBaşbakan nesnesini geri döndürmektedir. Lakin her VekilBaşbakan nesnesi aynı zamanda bir Başbakan nesnesi olduğundan, bu metodu çağıran Vatandaş için bir problem yoktur.

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public class BasbakanlikKalemi {
	
	private Basbakan basbakan;
	
	public BasbakanlikKalemi(){
		basbakan = new VekilBasbakan();
	}

	public Basbakan banaBasbakaniVer(){
		System.out.println("Basbakanlık Kalemi: Tabi efendim");
		return basbakan;
	}
}

 

Vatandaş sınıfı, BaşbakanlıkKalemi’nden aldığı Başbakan nesnesiyle konuşmakta ve derdini anlatıp, oğluna iş istemekte ve mutlu bir şekilde işini bitirmektedir.

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public class Vatandas {
	private Basbakan basbakan;
	
	public Vatandas(BasbakanlikKalemi kalem){
		basbakan = kalem.banaBasbakaniVer();
	}

	public String derdiniAnlat(){
		basbakan.dertDinle("Bir derdim var...");
		return "Yasasiiinnn!!!";
	}
	
	
	public String isIste(){
		basbakan.isBul("Oglum");
		return "Yasasiiinnn!!!";
	}
}

 

Son olarak da bu sistemi çalıştıran ve main metoda sahip olan Test sınıfı da şöyledir:

package org.javaturk.dp.pattern.gof.structural.proxy.basbakan;

public class Test {

	public static void main(String[] args) {
		BasbakanlikKalemi kalem = new BasbakanlikKalemi();
		Vatandas riza = new Vatandas(kalem);
		riza.derdiniAnlat();
		riza.isIste();
	}
}

 

Test sınıfını çalıştırdığımızda çıktımız da şöyle olur:

Başbakanlık Kalemi: Tabi efendim
Vekil: Derdinizi dinliyorum.
Basbakan: Dinliyorum.
Vekil: Isteginizi dinliyorum.

 

Bu kodlar ile Proxy kalıbının tipik bir uygulamasını görmüş olduk. Bu kalıp ile şunları sağladık:

  • Düzgün bir görev dağılımı: Herkes kendi işini yapıyor ve diğerleriyle haberleşiyor.
  • Gerçek başbakanı koruma: Hiç bir vatandaş doğrudan başbakana ulaşamıyor ama bundan haberi de yok, ulaştığını düşünüyor. Başbakana sadece vekil ulaşıyor çünkü vekilden eminiz, onun görevi bellidir.
  • Vatandaşın derdini başbakana anlatması.
  • Başbakanın ya da kontrol kurallarının değişmesinden vatandaş etkilenmemesi. Çünkü Vatandaş, arayüze güveniyor, onun gerçekleştirmesine değil: Program to an interface, not an implementation.

Bu yapıyla ilgili duruma göre şöyle değişiklikler de yapılabilir:

  • GerçekBaşbakan, singleton olabilir. Bu durumda başka hiç kimse GerçekBaşbakan‘ın nesnesini oluşturamaz.
  • VekilBaşbakan‘ın birden fazla nesnesi olabilir. Yani eğer Vatandaş sayısı fazla ise bu durumda vatandaşları sırada bekletmemek için VekilBaşbakan‘ın nesnelerinden oluşan bir havuz kurgulanabilir. Bu durumda her Vatandaş nesnesi farklı bir VekilBaşbakan nesnesiyle konuşacaktır. Bu şekilde aynı anda pek çok Vatandaş nesnesine hizmet verilebilecektir. Bu durumun tek problemi, bir çok VekilBaşbakan nesnelerinin ellerindeki dertleri GerçekBaşbakan‘a nasıl iletecekleridir. Çünkü bu durumda bir planlama gereklidir. VekilBaşbakan nesneleri eğer birer kanal (thread) olursa, bu durumda GerçekBaşbakan‘a ulaşmalarının kontrollü yani synchronized olması gerekecektir.

Şimdi size bir soru ile bu yazıyı bitirelim: Proxy kalıbını kullanabileceğiniz ya da kullandığınız ne gibi durumlar olabilir ya da oldu? Bu kalıbı probleminizi çözmede nasıl kullanırsınız ya da kullandınız? Temel nesneler neler olabilir ya da nelerdi?

 

Toplam görüntülenme sayısı: 1402