Шаблон прокси - Применимость и примеры - PullRequest
3 голосов
/ 12 марта 2012

Отсюда: http://www.oodesign.com/proxy-pattern.html

Применимость и примеры

Шаблон проектирования Proxy применяется, когда необходимо контролировать доступ к объекту., а также когда есть необходимость в сложной ссылке на объект.Распространенные ситуации, в которых применяется шаблон прокси:

Виртуальные прокси : задержка создания и инициализации дорогих объектов до момента необходимости, когда объекты создаются по требованию (например, создание объекта RealSubjectтолько когда вызывается метод doSomething).

Защитные прокси : где прокси-сервер контролирует доступ к методам RealSubject, предоставляя доступ к некоторым объектам и отказывая в доступе другим.

Smart References : предоставление сложного доступа к определенным объектам, например отслеживание количества ссылок на объект и отказ в доступе при достижении определенного числа, а также загрузка объекта из базы данных в память по требованию.

Итак, нельзя ли создать виртуальных прокси , создав отдельную функцию (не являющуюся конструктором) для нового объекта?

Не можем ли создать прокси защиты просто сделав функцию приватной и разрешив доступ только производным классам?ИЛИ через класс друга?

Нельзя Smart References создать статическую переменную-член, которая подсчитывает количество созданных объектов?

В каких случаяхметод Proxy должен быть предпочтительным для спецификаторов доступа и наследования?

Какой смысл мне не хватает?

Ответы [ 4 ]

3 голосов
/ 12 марта 2012

Ваши вопросы немного абстрактны, и я не уверен, что могу ответить вообще хорошо, но вот мои мысли по каждому из них.Лично я не согласен, что некоторые из этих вещей - лучший дизайн для работы, но это не ваш вопрос, а вопрос мнения.

Виртуальные прокси Я непонять, что вы пытаетесь сказать здесь вообще.Суть паттерна здесь в том, что у вас может быть объект A, который, как вы знаете, будет занимать 100 МБ, и вы не знаете наверняка, что вам когда-нибудь понадобится использовать этот объект.

Чтобы избежать выделения памяти длядо тех пор пока этот объект не понадобится, вы создаете фиктивный объект B, который реализует тот же интерфейс, что и A, и если любой из его методов вызывается B, создает экземпляр A, таким образом избегая выделения памяти до тех пор, пока он не понадобится.

Защита прокси Здесь я думаю, что вы неправильно поняли использование шаблона.Идея состоит в том, чтобы иметь возможность динамически контролировать доступ к объекту.Например, вы можете захотеть, чтобы класс A имел доступ к методам класса B , если условие C не является истинным.Как я уверен, вы можете видеть, что этого нельзя достичь с помощью спецификаторов доступа.

Умные ссылки Здесь я думаю, что вы неправильно понимаете необходимость умных указателей.Поскольку это довольно сложная тема, я просто предоставлю ссылку на вопрос о них: RAII и умные указатели на C ++

Если вы никогда не программировали на языке, подобном C, где вы управляетеВаша память сама по себе, это может объяснить путаницу.

Я надеюсь, что это поможет ответить на некоторые ваши вопросы.

РЕДАКТИРОВАТЬ:

Я не заметил, что это было помеченоС ++, так что я предполагаю, что вы действительно понимаете необходимость очистки динамической памяти.Один статический счетчик ссылок будет работать, только если вы намереваетесь когда-либо иметь один экземпляр вашего объекта.Если вы создаете 2000 экземпляров объекта, а затем удаляете 1999 из них, ни у одного из них не освободится память до последнего оставленного объема, что явно нежелательно (предполагается, что вы отслеживали расположение всей выделенной памяти).чтобы иметь возможность освободить его!).

РЕДАКТИРОВАТЬ 2:

Скажем, у вас есть класс следующим образом:

class A {
public:  
  static int refcount;

  int* allocated_memory;

  A() { 
    ++refcount;
    allocated_memory = new int[100000000];
  }

  ~A() { 
    if(! --refcount) {
      delete [] allocated_memory;
    }
  }
}

И некоторый код, который использует его:

int main() {
  A problem_child;  // After this line refcount == 1
  while(true) {
    A in_scope;     // Here refcount == 2

  }                 // We leave scope and refcount == 1. 
                    // NOTE: in_scope.allocated_memory is not deleted
                    //       and we now have no pointer to it. Leak!
  return;
} 

Как видно из кода, refcount считает все ссылки на все объекты, что приводит к утечке памяти.Я могу объяснить подробнее, если вам нужно, но это действительно отдельный вопрос.

1 голос
/ 12 марта 2012

Я не эксперт, но вот мои мысли о Виртуальных прокси : если мы контролируем инициализацию с помощью отдельной функции, скажем bool Create();, тогда ответственность и контроль инициализации лежит на клиенте класса,При использовании виртуальных прокси цель состоит в том, чтобы сохранить контроль над созданием в классе, не обращая на это внимания клиента.

Защитные прокси: Защищенный Субъект может иметь разныевиды клиентов, которым нужен незащищенный / неограниченный доступ ко всем подчиненным методам , а другим, которым должен быть разрешен доступ к подмножеству методов, следовательно, необходим прокси-сервер защиты.

0 голосов
/ 12 марта 2012

Хорошо бы спросить, есть ли альтернативы стандартным решениям проблем.Шаблоны проектирования представляют собой решения, которые работали для многих людей, и имеют преимущество в том, что есть хороший шанс, что опытный программист, пришедший к коду, распознает шаблон и, таким образом, обнаружит, что поддержка кода проще.Тем не менее, все проекты представляют собой компромиссы, а шаблоны имеют свои затратыТаким образом, вы правы, оспаривая использование шаблонов и рассматривая альтернативы.

Во многих случаях разработка заключается не только в том, чтобы заставить код работать, но и в том, как он структурирован.Какой кусок кода "знает" что.Вы предлагаете альтернативу для Virtual Prozy и переносите (как говорит fizzbuzz) знание о создании с прокси на клиент - клиент должен «знать», чтобы вызывать Create (), и поэтому знает о жизненном цикле класса.В то время как с прокси-сервером он просто создает объект, который он рассматривает как работника, тогда незаметное создание происходит, когда прокси-сервер решает, что это имеет смысл.Этот рефакторинг ответственности в прокси-сервер считается ценным, он позволяет нам в будущем изменять эти правила жизненного цикла без каких-либо клиентов.

Защитный прокси: ваше предложение требует, чтобы клиенты имели отношения наследования, чтобыони могут использовать защищенные методы.Вообще говоря, это слишком тесно связывает клиента и работника, поэтому мы представляем прокси.

Умная ссылка: нет, один статический счет не годится.Вам нужно сосчитать ссылки на отдельные экземпляры.

Если вы тщательно проработаете каждый случай, то обнаружите, что в шаблонах проектирования есть свои достоинства.Если вы попытаетесь реализовать альтернативу, вы начнете с некоторого кода, который выглядит проще, чем шаблон проектирования, а затем обнаружите, что по мере того, как вы начнете реорганизовывать и улучшать код, устраняя дублирование и так далее, вы в конечном итоге изобретаете шаблон проектирования - и это действительно приятнорезультат.

0 голосов
/ 12 марта 2012

Прокси-объект - это объект, который ведет себя как другой объект для добавления некоторого контроля / поведения.Умный указатель - хороший пример: он обращается к объекту так, как если бы вы использовали необработанный указатель, но он также контролирует время жизни этого объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...