
Замісник на C#
Замісник — це об’єкт, який виступає прошарком між клієнтом та реальним сервісним об’єктом. Замісник отримує виклики від клієнта, виконує свою функцію (контроль доступу, кешування, зміна запиту та інше), а потім передає виклик сервісному об’єктові.
Замісник має той самий інтерфейс, що і реальний об’єкт, тому для клієнта немає різниці — працювати з реальним об’єктом безпосередньо, чи за допомогою замісника.
Складність:
Популярність:
Застосування: Патерн Замісник застосовується в коді на C# тоді, коли потрібно замінити дійсний об’єкт його сурогатом, причому, непомітно для клієнтів цього об’єкта. Це дозволить виконати додаткові поведінки до або після основної поведінки дійсного об’єкта.
Ознаки застосування патерна: Клас замісника найчастіше делегує всю справжню роботу своєму реальному об’єктові. Замісники часто самі стежать за життєвим циклом свого реального об’єкта.
Концептуальний приклад
Цей приклад показує структуру патерна Замісник, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.
Program.cs: Приклад структури патерна
using System;
namespace RefactoringGuru.DesignPatterns.Proxy.Conceptual
{
// The Subject interface declares common operations for both RealSubject and
// the Proxy. As long as the client works with RealSubject using this
// interface, you'll be able to pass it a proxy instead of a real subject.
public interface ISubject
{
void Request();
}
// The RealSubject contains some core business logic. Usually, RealSubjects
// are capable of doing some useful work which may also be very slow or
// sensitive - e.g. correcting input data. A Proxy can solve these issues
// without any changes to the RealSubject's code.
class RealSubject : ISubject
{
public void Request()
{
Console.WriteLine("RealSubject: Handling Request.");
}
}
// The Proxy has an interface identical to the RealSubject.
class Proxy : ISubject
{
private RealSubject _realSubject;
public Proxy(RealSubject realSubject)
{
this._realSubject = realSubject;
}
// The most common applications of the Proxy pattern are lazy loading,
// caching, controlling the access, logging, etc. A Proxy can perform
// one of these things and then, depending on the result, pass the
// execution to the same method in a linked RealSubject object.
public void Request()
{
if (this.CheckAccess())
{
this._realSubject.Request();
this.LogAccess();
}
}
public bool CheckAccess()
{
// Some real checks should go here.
Console.WriteLine("Proxy: Checking access prior to firing a real request.");
return true;
}
public void LogAccess()
{
Console.WriteLine("Proxy: Logging the time of request.");
}
}
public class Client
{
// The client code is supposed to work with all objects (both subjects
// and proxies) via the Subject interface in order to support both real
// subjects and proxies. In real life, however, clients mostly work with
// their real subjects directly. In this case, to implement the pattern
// more easily, you can extend your proxy from the real subject's class.
public void ClientCode(ISubject subject)
{
// ...
subject.Request();
// ...
}
}
class Program
{
static void Main(string[] args)
{
Client client = new Client();
Console.WriteLine("Client: Executing the client code with a real subject:");
RealSubject realSubject = new RealSubject();
client.ClientCode(realSubject);
Console.WriteLine();
Console.WriteLine("Client: Executing the same client code with a proxy:");
Proxy proxy = new Proxy(realSubject);
client.ClientCode(proxy);
}
}
}
Output.txt: Результат виконання
Client: Executing the client code with a real subject:
RealSubject: Handling Request.
Client: Executing the same client code with a proxy:
Proxy: Checking access prior to firing a real request.
RealSubject: Handling Request.
Proxy: Logging the time of request.