Зачем использовать шаблон прокси, если мы можем отложить дорогостоящие процедуры в RealClass?

Недавно я читал шаблоны проектирования, и есть что-то, чего я не понимаю в прокси-шаблоне.

цитата из книги:

  1. Виртуальный прокси создает дорогостоящие объекты по требованию. ImageProxy, описанный в Мотивации, является примером такого прокси.

Я понимаю, что этот шаблон можно использовать для создания дорогих объектов по запросу. И этот пример также хорошо иллюстрирует использование.

Ниже представлен конструктор проксируемого класса RealImage. Метод loadFromDisk() обозначает дорогостоящую процедуру.

   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }

А прокси-класс ProxyImage в примере делает именно то, для чего он предназначен: создавать дорогие объекты по требованию.

Но мой вопрос: почему мы не можем просто удалить дорогостоящий метод loadFromDisk() из конструктора и поместить его туда, где он абсолютно необходим,

как здесь?

  public void display() {
      if(!loaded){
          loadFromDisk(fileName);
          loaded = true;
      }
      //then display
   }

Так зачем вообще использовать прокси?


person du369    schedule 21.02.2016    source источник


Ответы (1)


Проблемой, которую решает шаблон прокси в этой ситуации, является дублирование кода. Представьте ситуацию, когда у вас есть десятки методов, похожих на display(), где нужно проверить флаг loaded. Ваш код будет выглядеть так:

public void display() {
    if(!loaded){
        loadFromDisk(fileName);
        loaded = true;
    }
    //then display
}
public void resize(double scale) {
    if(!loaded){
        loadFromDisk(fileName);
        loaded = true;
    }
    //then resize
}
... // more methods go here
public void save() {
    if(!loaded){
        loadFromDisk(fileName);
        loaded = true;
    }
    //then save
}

Даже если вы поместите код if(!loaded){... в метод и вызовете его из всех методов, вам нужно не забыть выполнить вызов. Это подвержено ошибкам и может вызвать проблемы в будущем, особенно для новых программистов, начинающих работать над проектом.

person Sergey Kalinichenko    schedule 21.02.2016
comment
Что делать, если в RealClass есть несколько дорогостоящих процедур, и каждая из них нужна для разных методов? Как быть с этим с Proxy Pattern? Не будет ли это менее эффективным, потому что create on demand ProxyClass на самом деле вызовет некоторые дорогие, но ненужные процедуры? - person du369; 21.02.2016
comment
@ du369 Прокси не предназначен для работы с медленным построением объектов. Дорогие конструкторы — это только один конкретный случай, когда прокси полезен, но в основном идея прокси заключается в том, чтобы скрыть некоторые сведения об объекте за интерфейсом. Когда у вас есть несколько дорогостоящих методов, вы можете также позволить первому вызывающему методу нести расходы на их вызов, а затем кэшировать результат. - person Sergey Kalinichenko; 21.02.2016