Шаблон невиртуального интерфейса

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Шаблон невиртуального интерфейса (англ. non-virtual interface pattern, NVI) управляет переопределением методов в базовом классе. Такие методы могут вызываться из клиентского кода и переопределяемых методов, содержащих основную функциональность[1]. Этот шаблон тесно связан с шаблонным методом. Шаблон невиртуального интерфейса имеет все преимущества неабстрактного метода, вызывающего абстрактные методы, выполняющие реальную работу. Этот уровень косвенности позволяет выполнять операции до и после абстрактных операций — как непосредственно, так и при условии возможных непредвиденных изменений в будущем. Шаблон невиртуального интерфейса может быть использован с весьма малыми затратами на производство программного обеспечения и его высокой производительностью. Многие коммерческие программные фреймворки используют шаблон невиртуального интерфейса.

Преимущества и недостатки

[править | править код]

Использование этого шаблона приводит к разделению интерфейса класса на два отдельных интерфейса:

  1. Клиентский интерфейс: общедоступный невиртуальный интерфейс.
  2. Интерфейс подкласса: закрытый интерфейс, который может иметь любую комбинацию виртуальных и невиртуальных методов.

С такой структурой проблема хрупкого базового класса смягчается. Единственным недостатком является то, что код немного увеличен в размерах[2].

Пример на C#

[править | править код]
public abstract class Saveable
{
    // Фиксированная обработка определена в невиртуальном интерфейсе.
    // Поведение, определённое таким образом, наследуется всеми производными классами.
    // Например, создание и фиксация транзакции.
    public void Save()
    {
        Console.WriteLine("Creating transaction");
        CoreSave();
        Console.WriteLine("Committing transaction");
    }

    // Варианты обработки определяются в интерфейсах подклассов.
    // Это поведение может быть настроено по мере необходимости подклассами.
    // Например, конкретная реализация сохранения в базе данных.
    protected abstract void CoreSave();
}

public class Customer : Saveable
{
    public string Name { get; set; }
    public decimal Credit { get; set; }

    protected override void CoreSave()
    {
        Console.WriteLine("Saved customer {0} with credit limit {1}", Name, Credit);
    }
}

[3][4]

  1. Carr, Richard Non-Virtual Interface Design Pattern. BlackWasp (3 сентября 2011). — «The non-virtual interface pattern is a design pattern that controls how methods in a base class are overridden. Base classes include public, non-virtual members that may be called by clients and a set of overridable methods containing core functionality.» Дата обращения: 12 сентября 2012. Архивировано 14 сентября 2012 года.
  2. Tambe, Sumant Non-Virtual Interface (NVI) idiom and the design intent. C++ truths (11 апреля 2007). Дата обращения: 12 сентября 2012. Архивировано 26 сентября 2013 года.
  3. Non-Virtual Interface Design Pattern. www.blackwasp.co.uk. Дата обращения: 19 сентября 2021. Архивировано 19 сентября 2021 года.
  4. Non-Virtual Interface Design Pattern (Page 2 of 2). www.blackwasp.co.uk. Дата обращения: 19 сентября 2021. Архивировано 19 сентября 2021 года.