Vekil tasarım deseni;
- Oluşturulması zaman alan bir nesne yaratılması gerektiğinde
- Uzaktan erişilerek bir nesne yaratılması gerektiğinde
- Nesneye erişmeden önce bazı kontroller yapılması gerektiğinde
- Nesneye erişimin kısıtlı olduğunda yararlı olabilir.
Tasarım Şablonunun Gerçeklenmesi
Vekil kalıp tasarım kalıbında bir gerçek nesne bir de vekil nesne vardır. Vekil nesne gerçek nesnenin fonksiyonlarını kullanır. Yani istemci, işlemini vekil nesne üzerinden yapar. Bu yüzden gerçek nesnenin yapacağı iş vekil nesnenin kararıyla belirlenir. Vekil nesne sayesinde nesneye erişim sıklıkla olmayacak ve işlem daha verimli olacaktır.
Vekil tasarım kalıbının UML diyagramı aşağıdaki şekildedir;
Vekil Kalıp İle İlgili Uygulama
Hazırlanan örnek uygulamada bir video dosyası byte-byte kopyalanacak ve daha sonra bu kopyalanan dosya oynatılacaktır. Bunun için bir WPF (Windows Presentation Foundation) projesi açılıp, gerekli sınıflar oluşturulur. Öncelikle kopyalama işlemi için "Kopyalayici" isimli sınıf oluşturulur. Yapıcı metot içerisinde "Kopyala" isimli metot çağrılır ve böylece kopyalama işlemi tetiklenir.
//Gerçek nesne
class Kopyalayici
{
string kaynak;
string hedef;
public Kopyalayici(string kaynak, string hedef)
{
this.kaynak = kaynak;
this.hedef = hedef;
Kopyala();
}
public void Kopyala()
{
//okuma stream'i
FileStream streamIn = new FileStream(kaynak, FileMode.Open);
//yazma stream'i
FileStream streamOut = new FileStream(hedef, FileMode.Create);
//veri okuma
byte[] okunan = new byte[streamIn.Length];
streamIn.Read(okunan, 0, okunan.Length);
streamIn.Close();
//veri yazma
streamOut.Write(okunan, 0, okunan.Length);
streamOut.Close();
}
}
"KopyalayiciProxy" isimli sınıfta ise Kopyalayici türünden bir adet nesne oluşturulur. Ancak daha önce oluşturulan bir nesnenin tekrar oluşturulmasını engellemek amacıyla if koşulu kullanılır. Kopyala metodundan geriye dönen boolean değer ile kullanıcı bilgilendirilir.
//Proxy nesne
class KopyalayiciProxy
{
Kopyalayici kopyalayici;
public KopyalayiciProxy() { }
public bool Kopyala(string kaynak, string hedef)
{
bool sonuc;
if (kopyalayici == null)
{
sonuc = true;
kopyalayici = new Kopyalayici(kaynak, hedef);
}
else
{
sonuc = false;
}
return sonuc;
}
}Oluşturulan sınıfları kullanacak WPF formunun tasarımı ise aşağıdaki gibidir.
<Grid>
<MediaElement Height="282" HorizontalAlignment="Left" Margin="36,51,0,0"
Name="mediaElemet1" VerticalAlignment="Top" Width="381"
LoadedBehavior="Manual" UnloadedBehavior="Stop"
Stretch="Fill"></MediaElement>
<Label Content="bilgi" Height="28" HorizontalAlignment="Left"
Margin="193,10,0,0" Name="bilgiLabel" VerticalAlignment="Top"></Label>
<Button Content="Button" Height="23" HorizontalAlignment="Left"
Margin="193,12,0,0" Name="button1" VerticalAlignment="Top" Width="75"
Click="button1_Click" />
</Grid>
Oluşturulan WPF formun sınıfında bulunan "hedefDosya" isimli dosya, kopyalama işlemi yapıldıktan sonra kullanılacak olan dosyadır. Uygulamada asıl işlemi yerine getiren sınıf "Kopyalayici" isimli sınıf olmasına rağmen, istemci doğrudan bu sınıfa erişmemektedir. "KopyalayiciProxy" sınıfı üzerindeki metot aracılığıyla gerçek nesneye görev gönderimi yapılıp yapılmayacağına karar verilir.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
KopyalayiciProxy proxy = new KopyalayiciProxy();
Stopwatch saat = new Stopwatch();
string kaynakDosya = @"D:\MTvideo.wmv";
string hedefDosya = @"D:\MTvideo1.wmv";
private void button1_Click(object sender, RoutedEventArgs e)
{
saat.Restart();
bool sonuc = proxy.Kopyala(kaynakDosya, hedefDosya);
saat.Stop();
if (sonuc)
{
bilgiLabel.Content = "Kopyalandı. Süre: "
+ saat.Elapsed.TotalMilliseconds.ToString();
}
else
{
bilgiLabel.Content = "Daha önceki kopya kullanılıyor. Süre: "
+saat.Elapsed.TotalMilliseconds.ToString();
}
//Video oynat
mediaElemet1.Source = new Uri(hedefDosya);
mediaElemet1.Play();
}
}
Uygulama çalıştırıldığında ilk olarak oynatılacak dosyanın açılma süresi yaklaşık 0,5 sn iken ikinci kez oynatılmak istenildiğinde 0,002 sn olarak görülmektedir.