Sobes.tech
Назад к вопросам
Junior — Middle
57

Можешь привести пример шаблона проектирования, который разделяет обязанности между компонентами?

Компании, где спрашивали
Банк ПСБ

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Ожидают пример паттерна, где каждая часть системы отвечает только за свою задачу, а логика не смешивается в одном классе. Хороший ответ — назвать, например, MVC, Mediator или Facade и кратко объяснить, как он разделяет ответственность. Важно показать, что такой подход упрощает поддержку, тестирование и изменение кода.

Определение:

Шаблон проектирования, который разделяет обязанности между компонентами, — это способ организовать код так, чтобы каждый класс или модуль выполнял ограниченную и понятную роль. Это снижает связанность между частями системы и делает архитектуру более гибкой. Примером может быть паттерн Mediator, где объекты не общаются напрямую, а взаимодействуют через посредника.

Пример использования:

Допустим, есть форма с несколькими полями ввода и кнопкой отправки. Вместо того чтобы каждое поле напрямую проверяло состояние других полей, можно вынести координацию в отдельный объект-посредник.

using System;
using System.Collections.Generic;

interface IMediator
{
    void Notify(object sender, string ev);
}

class ConcreteMediator : IMediator
{
    public TextBox1 Field1 { get; set; }
    public TextBox2 Field2 { get; set; }
    public Button SubmitButton { get; set; }

    public void Notify(object sender, string ev)
    {
        if (ev == "Changed")
        {
            SubmitButton.Enabled = !string.IsNullOrWhiteSpace(Field1.Text)
                                && !string.IsNullOrWhiteSpace(Field2.Text);
        }
    }
}

class TextBox1
{
    private IMediator _mediator;
    public string Text { get; set; }

    public TextBox1(IMediator mediator) => _mediator = mediator;

    public void ChangeText(string text)
    {
        Text = text;
        _mediator.Notify(this, "Changed");
    }
}

class TextBox2
{
    private IMediator _mediator;
    public string Text { get; set; }

    public TextBox2(IMediator mediator) => _mediator = mediator;

    public void ChangeText(string text)
    {
        Text = text;
        _mediator.Notify(this, "Changed");
    }
}

class Button
{
    public bool Enabled { get; set; }
}

class Program
{
    static void Main()
    {
        var mediator = new ConcreteMediator();
        var field1 = new TextBox1(mediator);
        var field2 = new TextBox2(mediator);
        var button = new Button();

        mediator.Field1 = field1;
        mediator.Field2 = field2;
        mediator.SubmitButton = button;

        field1.ChangeText("Hello");
        field2.ChangeText("World");

        Console.WriteLine(button.Enabled); // True
    }
}

Пояснение кода:

Код показывает паттерн Mediator. TextBox1 и TextBox2 не знают друг о друге и не проверяют состояние напрямую. При изменении текста они уведомляют ConcreteMediator. Посредник получает событие и сам решает, можно ли включить кнопку SubmitButton.

Это разделяет обязанности так:

  • поля отвечают только за хранение и изменение своего текста;
  • кнопка отвечает только за свое состояние;
  • посредник отвечает за бизнес-логику взаимодействия между ними.

Ключевые моменты:

  • Паттерны такого типа уменьшают связанность между компонентами.
  • Каждый класс получает узкую и понятную ответственность.
  • Это упрощает тестирование: можно отдельно проверять компоненты и логику координации.
  • Mediator особенно полезен, когда объектов взаимодействия много и связи между ними становятся сложными.
  • Альтернативой часто бывает Facade, если нужно упростить доступ к подсистеме, а не координировать общение объектов.