GoF’a göre: “Provide a surrogate or placeholder for another object to control access to it.“
“Başka bir nesneye erişimi kontrol etmesi için bir vekil veya yer tutucu sağlayın.”
Tanımın kendisi çok açıktır. Bir işlevselliğe kontrollü erişim sağlamak istediğimizde proxy tasarım deseni kullanılır. Diyelim ki sistemde bazı komutları çalıştırabilen bir sınıfımız var. Şimdi kullanıyorsak sorun yok ama bu programı bir istemci uygulamasına vermek istiyorsak ciddi sorunları olabilir çünkü istemci programı bazı sistem dosyalarını silmek veya istemediğiniz bazı ayarları değiştirmek için komut verebilir. Burada programın kontrollü erişimini sağlamak için bir proxy sınıfı oluşturulabilir.
UML Class Diyagramı
Kullanım Sıklığı: orta-yüksek
Proxy Prensipleri
- Proxy: proxy’nin gerçek konuya erişmesine izin veren bir referans tutar. RealSubject ve Subject arayüzleri aynıysa, Proxy bir Konuya atıfta bulunabilir. Gerçek öznenin yerine bir proxy’nin konulabilmesi için Özne’ninkine benzer bir arabirim sağlar.
- Subject: RealSubject ve Proxy için ortak interface tanımlar, böylece Proxy, RealSubject’in beklendiği her yerde kullanılabilir.
- RealSubject: proxy’nin temsil ettiği gerçek nesneyi tanımlar.
C# Proxy Design Pattern Uygulama
Bu senaryomuzda bir komut sınıfı tasarlayacağız komut sınıfımıza kodu çalıştırmak için client tarafından gönderilen komuta proxy tasarım modelini uygulayarak komutun kontrol edilmesini sağlayacağız. Komut admin tarafından yazılmış olursa çalıştırılacaktır.
Komut sınıfımız için interface tanımlıyoruz.
public interface ICommandExecutor
{
public void runCommand(string cmd);
}
Interface’i implement ediyoruz.
public class CommandExecutorImp : ICommandExecutor
{
public void runCommand(string cmd)
{
Console.WriteLine(cmd + " command executed.");
}
}
Proxy Class, Şimdi sadece admin kullanıcıların yukarıdaki sınıfın tam erişimine sahip olmasını sağlamak istiyoruz, eğer kullanıcı admin değilse, o zaman sadece sınırlı komutlara izin verilecektir.
public class CommandExecutorProxy : ICommandExecutor
{
private bool isAdmin;
private ICommandExecutor executor;
//Yapıcı metodun görevi kullancı bilgileri doğru ise bir vekil komut nesnesini oluşturacak.
public CommandExecutorProxy(string user, string pwd)
{
if (user == "admin" && pwd=="123")
{
isAdmin = true;
executor = new CommandExecutorImp();
}
}
public void runCommand(string cmd)
{
if (isAdmin)
{
executor.runCommand(cmd);
}
else
{
Console.WriteLine("this command is not allowed for non-admin users.");
}
}
}
Program.cs – Main Method
//şifreyi bilinçli olarak yanlış giriyoruz.
ICommandExecutor executor = new CommandExecutorProxy("admin", "321");
try
{
executor.runCommand("ls -ltr");
}
catch (Exception e)
{
Console.WriteLine("Exception Message: " + e.Message);
}
Sonuç
this command is not allowed for non-admin users.
Proxy tasarım deseninin yaygın kullanımları, erişimi denetlemek veya daha iyi performans için bir sarmalayıcı uygulaması sağlamaktır.