Идиома невиртуального интерфейса (Nonvirtual interface)

      Комментарии к записи Идиома невиртуального интерфейса (Nonvirtual interface) отключены

Главная Форумы Программирование Технология программирования Паттерны Идиома невиртуального интерфейса (Nonvirtual interface)

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 5 мес., 2 нед. назад.

  • Автор
    Сообщения
  • #3618

    Основная задача этого паттерна — разделение представления интерфейса и его реализации. Виртуальные функции объявляются как private или protected, а их вызов происходит внутри обычных функций, которые и предоставляются пользователю.

    #include <string>
    #include <memory>
    
    class base
    {
    public:
    
        virtual ~base() {}
    
        void show()
        {
            do_show();
        }
    
        void load(std::string const& filename)
        {
            // Здесь можно проверить, существует ли файл
            do_load(filename);
            // Здесь можно проверить, валидны ли прочитанные данные
        }
    
        void save(std::string const& filename)
        {
            do_save(filename);
            // Здесь можно проверить, успешно ли прошла запись
        }
    
    protected:
    
        virtual void do_show() = 0;
        virtual void do_load(std::string const& filename) = 0;
        virtual void do_save(std::string const& filename) = 0;
    };
    
    class derived : public base
    {
    protected:
    
        virtual void do_show() {}
        virtual void do_load(std::string const& filename) {}
        virtual void do_save(std::string const& filename) {}
    };
    
    int main()
    {
        typedef std::auto_ptr<base> base_ptr;
    
        base_ptr b(new derived);
    
        b->load("D:/Schema.xml");
        b->show();
        b->save("E:/Schema.xml");
    
        return 0;
    }

    Предложенное разделение имеет определенные плюсы. Во-первых, внутри невиртуальной функции вы можете осуществлять всяческие проверки, как до вызова виртуальной функции, так и после него. Во-вторых, интерфейсы виртуальной и невиртуальной функции не обязаны совпадать. Открытая функция может иметь интерфейс, который будет наиболее удобен пользователю, а виртуальная — который будет наиболее удобен для замещения функциональности. Более того, набор и интерфейс виртуальных функций может быть совершенно иным, нежели набор и интерфейс открытых функций. Никто не мешает внутри открытой функции вызвать пять виртуальных. Паттерн позволяет четко разделить обязанности — в этом его достоинство и основное назначение. Открытые функции предоставляют интерфейс, который в первую очередь удобен пользователю. Виртуальные функции предоставляют интерфейс, который в первую очередь удобен для замещения функциональности.

Для ответа в этой теме необходимо авторизоваться.