🎉 Ура! Після трьох років роботи, я нарешті випустив англійську версію книжки про патерни! Ось вона »

C#: Заступник

Proxy Заступник Proxy

Заступник — це об’єкт, який виступає прошарком між клієнтом та реальним сервісним об’єктом. Заступник отримує виклики від клієнта, виконує свою функцію (контроль доступу, кешування, зміна запиту та інше), а потім передає виклик сервісному об’єктові.

Заступник має той самий інтерфейс, що і реальний об’єкт, тому для клієнта немає різниці — працювати з реальним об’єктом безпосередньо, чи за допомогою заступника.

Детальніше про Заступника

Особливості паттерна на C#

Складність:

Популярність:

Застосування: Патерн Заступник застосовується в коді на C# тоді, коли потрібно замінити дійсний об’єкт його сурогатом, причому, непомітно для клієнтів цього об’єкта. Це дозволить виконати додаткові поведінки до або після основної поведінки дійсного об’єкта.

Ознаки застосування патерну: Клас заступника найчастіше делегує всю справжню роботу своєму реальному об’єктові. Заступники часто самі стежать за життєвим циклом свого реального об’єкта.

Приклад: Структура патерну

Цей приклад показує структуру патерну Заступник, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

Program.cs: Приклад структури патерну

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Proxy.Structural
{
    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();

            client.ClientCode(proxy);
        }
    }

    public class Client
    {
        public void ClientCode(Subject subject)
        {
            subject.Request();
        }
    }

    public abstract class Subject
    {
        public abstract void Request();
    }

    class RealSubject : Subject
    {
        public override void Request()
        {
            Console.WriteLine("RealSubject: Handling Request.");
        }
    }

    class Proxy : Subject
    {
        RealSubject realSubject;
        
        public override void Request()
        {
            if (this.checkAccess())
            {
                realSubject = new RealSubject();
                realSubject.Request();

                this.logAccess();
            }

        }
		
        public bool checkAccess()
        {
            Console.WriteLine("Proxy: Checking access prior to firing a real request.");

            return true;
        }
		
        public void logAccess()
        {
            Console.WriteLine("Proxy: Logging the time of request.");
        }
    }
}

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.