Подтвердить что ты не робот

Вопросы о шаблоне прототипа

Я изучаю различные шаблоны дизайна, и у меня есть сильное чувство, что я не вижу существенной части (или частей) в понимании этой конкретной картины.

На всех сайтах, которые я просмотрел, и в книге GoF я вижу метод clone. Из того, что я понимаю, у нас есть некоторый тип объекта, который мы можем клонировать, когда нам нужны разные версии этого объекта, но мы не хотим, чтобы каждый из них создавал вручную, используя команду "new" (как в Java). Это может скрыть его конкретную реализацию. Поэтому, когда мы клонируем, мы можем немного модифицировать клон и сделать это, что нам нужно, не зная, как изначально создать этот объект. Я считаю это правильным?

Мне также говорят, что это может уменьшить подклассирование и впоследствии уменьшить количество классов, которые вам нужно сделать. Я не совсем понимаю эту часть. Может ли кто-нибудь помочь мне понять это?

Мой последний вопрос касается абстрактного метода factory (или даже метода factory). Эти шаблоны factory и образец прототипа чувствуют, что они пытаются скрыть конкретные реализации при создании новых объектов. Когда лучше выбрать один из другого?

Спасибо всем!

4b9b3361

Ответ 1

Шаблон прототипа

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

Пример

  • Дублирование DVD: дублирование главного DVD для создания нескольких копий.
  • Объект отчетности. Рассмотрим объект отчета, который содержит обработанную информацию для передачи в графический интерфейс. Исходный отчет содержит данные в порядке возрастания. Теперь, используя этот шаблон, можно создать аналогичный отчет, но с данными, отсортированными в порядке убывания.

Преимущества

  • Производительность: клонирование (используя MemberwiseClone) значительно дешевле, чем создание нового объекта заново (с новый оператор). Обратите внимание, что для выполнения глубокой копии необходимо переопределить MemberwiseClose().
  • Объекты могут быть клонированы очень динамично, без каких-либо настойчивых утверждений. Первый созданный объект может быть создан в любое время при выполнении приложения, а дальнейшее дублирование может быть выполнено в любое время вперед.

Когда использовать его

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

Сравнение с Factory Шаблон

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

Но разница между двумя шаблонами заключается в том, что для Factory Method концентрируется на создании одного объекта не существующего типа объекта как fresh creation (понимая точный подтип класса Creator). Шаблон Prototype использует сам класс, особенно производный класс для действия self duplication.


Factory Шаблон метода

В этом шаблоне клиент (или потребитель) задает Создателю (или factory) для определенного типа объекта из иерархии классов. Метод Creator класса Factory делегирует создание конкретного объекта производным классам и возвращает объект класса типа, заданного клиентом. По сути, у вас есть одна точка контакта для создания нескольких объектов иерархии классов.

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

Когда использовать

  • Гибкость важна (низкая связь)
  • Объекты могут быть расширены в подклассах
  • Существует определенная причина, по которой один подкласс выбирается над другим - эта логика является частью метода Factory.
  • Клиент делегирует обязанности подклассам в параллельных иерархиях.


Абстрактный шаблон Factory

Аннотация Factory идет на шаг выше (более абстрактно), чем шаблон метода Factory. В этом случае можно иметь не только одну, но и несколько фабрик с небольшими вариациями. Он отвечает за создание объектов, принадлежащих семействам иерархии классов, а не только одной иерархии классов.

Конкретный класс Factory уже существует. Но Factory будет иметь несколько различные методы. Каждый метод может создать экземпляр. Клиент может выбрать соответствующий метод и получить экземпляр.

Если вы примете пример MVC, основанного на идеальном архитектурном дизайне, клиент будет классом бизнес-контроллера, а Concrete Products - бизнес-объектами, Заводы являются вспомогательными (вспомогательными) контроллерами. Они работают вместе с запросом от Business Controller.

Когда использовать

  • Ожидается, что система будет независима от того, как создаются продукты. Он может даже ожидать независимости от того, как продукты составлены и представлены. Термин "продукт" относится к окончательно результирующему объекту, который разработчик клиента должен будет использовать, вызывая его методы.
  • Система, которая должна настраиваться с одним из нескольких семейств продуктов. Таким образом, фактический выбор семейства будет не во время кодирования, а в более позднее время конфигурации.
  • Семейство продуктов предназначено для совместной работы.
  • Создание для библиотеки продуктов. Озабоченность больше здесь - это соответствующий интерфейс, а не реализация.

Ответ 2

У вас есть образец прототипа по внешнему виду.

Как это уменьшает подклассы

Предположим, вы делаете MineCraft, и вы используете шаблон прототипа для каждого из разных блоков (например, грязь, камень и т.д.). Все объекты-прототипы представляют собой один и тот же класс Block, но каждый объект имеет на нем разные свойства, чтобы он выглядел и вел себя по-разному, например:

prototypes.dirt = new Block;
prototypes.dirt.texture = new Image("dirt.jpg");
prototypes.dirt.hardness = 1;

prototypes.stone = new Block;
prototypes.stone.texture = new Image("stone.jpg");
prototypes.stone.hardness = 9;

Итак, вместо подкласса, где вы пишете new DirtBlock или new StoneBlock, вместо этого вы должны написать prototypes.dirt.clone() или prototypes.stone.clone(). Подклассы не требуются, но при необходимости у вас есть возможность подкласса.

Различия Factory Шаблон

Что касается выбора шаблона прототипа вместо шаблона Factory, есть две ситуации, о которых я могу думать, где они отличаются:

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

    prototypes.allValues().objectAtIndex(rand() % prototypes.size()).clone();

    Если вы использовали метод Factory для создания блоков, было бы сложнее получить случайный блок.

  • Если создание объекта дорого, но копирование дешево, образец прототипа будет более эффективным. Например, возьмите этот метод Factory:

    Image loadUserImage() { 
        //loads from disk. will be slow
        return new JPEGImage("path/to/user/image.jpg"); 
    }
    

    Если этот метод будет вызываться повторно, было бы более эффективно использовать прототип, например:

    Image loadUserImage() {
        //copy in memory. will be fast
        return userImagePrototype.clone();
    }
    


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

Ответ 3

Усиление эффективности использования прототипа сомнительно. Не будет повышения эффективности, потому что на большинстве языков сам метод clone выполняет вызов new для того, чтобы построить собственный экземпляр объекта.

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