Паттерн свиш (паттерн мгновенного переноса)

Медицина
8 ноября 2019

Паттерн Flyweight (приспособленец)

Паттерн свиш (паттерн мгновенного переноса)

Паттерны » Структурные паттерны » Flyweight

Назначение паттерна Flyweight

  • Паттерн Flyweight использует разделение для эффективной поддержки большого числа мелких объектов.
  • Является стратегией Motif GUI для замены «тяжеловесных» виджетов «легковесными» гаджетами.

Motif–библиотека для разработки приложений c графическим интерфейсом под X Window System. Появилась в конце 1980-х и на данный момент считается устаревшей.

В Motif элементы графического интерфейса (кнопки, полосы прокрутки, меню и т.д.) строятся на основе виджетов. Каждый виджет имеет свое окно. Исторически окна считаются «тяжеловесными» объектами.

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

Гаджеты управляются менеджерами виджетов, использующих схему «parent-children».

Решаемая проблема

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

Обсуждение паттерна Flyweight

Паттерн Flyweight описывает, как совместно разделять очень мелкие объекты без чрезмерно высоких издержек. Каждый объект-приспособленец имеет две части: внутреннее и внешнее состояния.

Внутреннее состояние хранится (разделяется) в приспособленце и состоит из информации, не зависящей от его контекста.

Обратите внимание

Внешнее состояние хранится или вычисляется объектами-клиентами и передается приспособленцу при вызове его методов.

Замена Motif-виджетов «легковесными» гаджетами иллюстрирует этот подход. Если виджет являются достаточно самостоятельным элементом, то гаджет находится в зависимости от своего родительского менеджера компоновки виджетов. Каждый менеджер предоставляет своим гаджетам контекстно-зависимую информацию по обработке событий, ресурсам. Гаджет хранит в себе только контекстно-независимые данные.

Структура паттерна Flyweight

Клиенты не создают приспособленцев напрямую, а запрашивают их у фабрики. Любые атрибуты (члены данных класса), которые не могут разделяться, являются внешним состоянием. Внешнее состояние передается приспособленцу при вызове его методов. При этом наибольшая экономия памяти достигается в том случае, если внешнее состояние не хранится, а вычисляется при вызове.

UML-диаграмма классов паттерна Flyweight

Классы, описывающие различных насекомых Ant, Locust и Cockroach могут быть «легковесными», потому что специфичная для экземпляров информация может быть вынесена наружу и затем, передаваться клиентом в запросе.

Пример паттерна Flyweight

Паттерн Flyweight использует разделение для эффективной поддержки большого числа мелких объектов. Телефонная сеть общего пользования ТФОП является примером Flyweight.

Такие ресурсы как генераторы тональных сигналов (Занято, КПВ и т.д.), приемники цифр номера абонента, набираемого в тоновом наборе, являются общими для всех абонентов.

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

Использование паттерна Flyweight

  • Убедитесь, что существует проблема повышенных накладных расходов.
  • Разделите состояние целевого класса на разделяемое (внутреннее) и неразделяемое (внешнее).
  • Удалите из атрибутов (членов данных) класса неразделяемое состояние и добавьте его в список аргументов, передаваемых методам.
  • Создайте фабрику, которая может кэшировать и повторно использовать существующие экземпляры класса.
  • Для создания новых объектов клиент использует эту фабрику вместо оператора new.
  • Клиент (или третья сторона) должен находить или вычислять неразделяемое состояние и передавать его методам класса.

Особенности паттерна Flyweight

  • Если Flyweight показывает, как сделать множество небольших объектов, то Facade показывает, как представить целую подсистему одним объектом.
  • Flyweight часто используется совместно с Composite для реализации иерархической структуры в виде графа с разделяемыми листовыми вершинами.
  • Терминальные символы абстрактного синтаксического дерева Interpreter могут разделяться при помощи Flyweight.
  • Flyweight объясняет, когда и как могут разделяться объекты State.

Реализация паттерна Flyweight

Паттерн Flyweight: до и после

При использовании объектов на очень низких уровнях детализации накладные расходы могут быть непомерно большими. Использование паттерна Flyweight предполагает удаление неразделяемого состояния из класса и его передачу клиентом в вызываемые методы.

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

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

В этом примере, «X» состояние рассматривается как разделяемое, а «Y» состояние выносится наружу (передается клиентом при вызове метода report()).

До

class Gazillion { public: Gazillion() { m_value_one = s_num / Y; m_value_two = s_num % Y; ++s_num; } void report() { cout

Техника «Паттерн взмаха»

Паттерн свиш (паттерн мгновенного переноса)


Техника «Паттерн взмаха»,
наверное, одна из самых зрелищных в курсе НЛП и зачастую участники семинара сильно удивляются, когда человек, пытавшийся бросить курить в течение 10 лет, примерно через час спокойно контролирует свою привычку. Переход к желаемому состоянию в технике «Паттерн взмаха» осуществляется за счет изменения сенсорной микростратегии.

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

Сюда относится как кусание ногтей, грызение авторучек и других предметов, всяческие неконтролируемые манипуляции со своим лицом, пристрастие к семечкам, орехам, конфетам, шоколаду и другим продуктам питания, а также некоторые стадии курения и алкоголизма.

В принципе, техника «Паттерн взмаха» или ее элементы могут быть полезны и в других ситуациях, но прежде всего нужно хорошо проверить экологию предполагаемых изменений.

Изучив саму технику «Паттерн Взмаха», Вы поймете, что более точным для нее было бы название «Обретение контроля над автоматическим поведением с помощью визуального паттерна взмаха». То есть паттерн взмаха играет здесь сугубо техническую роль — изменяет старую сенсорную стратегию автоматического поведения и закрепляет новую.

Это означает, что сам по себе он наиболее подходит к простым ситуациям, когда человек сознательно решил и убедился в том, что хочет расстаться со своей привычкой. Например, он давно мечтает бросить курить или пить, но вот его руки продолжают по привычке «самостоятельно» тянуться за сигаретой или стаканом.

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

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

Что же представляет собой этот загадочный паттерн взмаха и как он работает?

Начнем с того, что «родное» название техники «Swish», которое аудиально передает скорость протекания данного паттерна.

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

Реализуется она примерно так: в поле зрения (восприятия) человека попадает предмет его «вожделения» (сигарета, конфета и т. д.), и тут же запускается привычное поведение. При этом человек может и не заметить, как, например, выкурил полпачки сигарет во время разговора в курящей компании.

Важно

И если сладкоежка обращает внимание на лежащую на столе плитку шоколада, то ему трудно сопротивляться возникшему желанию, «вплоть до победного истребления» всего шоколада в доме.

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

Заключается он в процессе параллельного изменения нескольких субмодальностей (плюс механизм ассоциации-диссициации – прим. А. Плигина) в момент последовательного перехода от одного визуального образа, запускающего прежнее поведение, к другому, отвечающему за новое поведение. При этом вся процедура повторяется несколько раз с постоянным ускорением вплоть до максимально быстрого воспроизведения всей стратегии. В результате качественного установления новой микростратегии старый триггер теперь так же стабильно запускает новое поведение.

Итак, в достаточно простых случаях мы могли бы использовать обычный паттерн взмаха, но реальная жизнь часто гораздо сложней. Одним из важных элементов любого негативного автоматического поведения (и не только) является наличие вторичных (побочных) выгод, которые его поддерживают…

Среди вторичных выгод для людей, у которых курение переросло во вредную привычку, встречаются такие, как: желание выглядеть более старшим или неординарным, самоутверждение, подростковая социализация, успокоение в стрессовой ситуации, концентрация в сложном положении, адаптация к чему-то новому, отдых во время интенсивной работы, заполнение пауз, временное «отключение» от текущих дел и др. Вы, наверное, уже заметили, что потребности, которые курящий человек удовлетворяет только с помощью сигареты, существуют в жизни каждого из нас. Некурящие студенты обычно спрашивают у курящих: «А как же все другие люди живут и справляются с подобными ситуациями без сигарет?» Один из возможных ответов заключается в недоверии человека самому себе, в низкой самооценке и поиске помощи «на стороне» (сигареты, алкоголь, наркотики, антидепрессанты, транквилизаторы, стимуляторы, психотерапевты и др.). Что имеется в виду? А то, что человек, машинально тянущийся за сигаретой в стрессовой ситуации, на самом деле убежден, что только она поможет ему успокоиться. И объяснить ему, что со всеми трудностями он справляется самостоятельно, а сигарета — это всего лишь ключ к нужному состоянию, очень нелегко. Еще более жесткую внешнюю зависимость часто имеют люди с хроническими или резко обостряющимися заболеваниями. Например, идет по улице совершенно спокойный человек, но вдруг вспоминает, что забыл дома «лекарства от сердца» — и ему уже можно вызывать «скорую помощь», так как испуг, который он при этом переживает, действительно может вызвать осложнение. Вот такую мощную силу имеют порой некоторые вещи: пока они с нами, мы чувствуем себя в полной безопасности, но стоит их забыть дома… И это не означает, что лекарства бесполезны: просто некоторые люди склонны больше полагаться на действенные средства (медикаменты, сигареты, амулеты и др.), чем на собственные силы.

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

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

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

Наверное, если бы люди внимательнее присмотрелись к себе, то были бы очень удивлены количеством всевозможных «танцев», которые они часто исполняют вместо того, чтобы сразу «нажать на рычаг».

Совет

Знаете ли вы семьи, где супруги считают, что в случае размолвки нужно выдержать паузу в час, день, месяц и более, прежде чем помириться? Как много людей, которые думают, что лучший способ привлечь внимание близкого человека — это «закатить» скандал? Сколько руководителей разного уровня действительно верят, что для достижения наибольшей эффективности в своей деятельности нужно начать с правдивой и своевременной критики?

Из всего вышесказанного можно сделать вывод: в случае обнаружения у человека вторичных выгод простое удаление негативного автоматического поведения (диета, кодирование, медикаментозное лечение, принудительное избавление от привычки и др.

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

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

Что же в таком случае предлагает НЛП?

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

Именно работа с вторичными выгодами является смысловым ядром техники паттерн взмаха, так как от нее во многом зависит устойчивость полученных изменений. Реализуется она с помощью создания специального образа «улучшенного себя, свободного от старой привычки».

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

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

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

После того как желаемый образ будет создан, на его основе вырабатываются предпочтительные варианты поведения. Для этого человеку предлагается мысленно поместить «улучшенного себя» на собственное место в жизни и посмотреть, как он будет вести себя в тех ситуациях, где раньше курил.

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

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

Что но собой представляет? Это какая-либо часть опыта человека, предшествующая негативному автоматическому поведению. Таким образом желательно, чтобы созданный ключ содержал в себе информацию из всех репрезентативных систем, которые задействованы в момент запуска негативного автоматического поведения. Визуальной части его уделяется особое внимание, т. к.

изменение стратегии в данном варианте техники происходит посредством визуальных субмодальностей.

Обратите внимание

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

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

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

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

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

Еще раз напомним, что техника паттерн взмаха (как и многие другие техники НЛП) не отучает человека от привычки, не удаляет симптом и не изменяет неэффективное поведение, а всего лишь возвращает ему утерянный контроль над собственными действиями и дает возможность осознанного выбора в тех ситуациях, где раньше она отсутствовала.

По материалам Центра НЛП в Образовании

Swish Pattern

Паттерн свиш (паттерн мгновенного переноса)

Swish Pattern to jedna z podstawowych i najskuteczniejszych technik w Neurolingwistycznym Programowaniu. Dzięki niej pozbędziesz się niechcianych nawyków, zachowań i kompulsji.

Swish dokonuje zmian w okablowaniu Twojego mózgu – łamie utarte ścieżki neuronalne tworząc jednocześnie nowe, które będą odpowiadać za korzystniejsze nawyki i zachowania. Technika jest bardzo prosta, więc do dzieła!

Swish Pattern służy przekotwiczaniu Twoich reakcji. Nawyki, których chcesz się pozbyć są niczym innym jak określonymi, utartymi schematami w postaci silnie wyrobionych ścieżek neuronalnych.

Важно

Wiedząc o tym, że każda myśl jest impulsem elektrycznym tworzącym nowe połączenia między komórkami nerwowymi w Twoim mózgu, możesz te schematy zmieniać za pomocą określonych ćwiczeń.

Swish jest jednym z nich i jest to jedna z najważniejszych technik w NLP.

Technika świstu jest bardzo skuteczna, działa szybko i jest łatwa w użyciu.

Na początek wybierz co chcesz zmienić – może to być jakiś nieprzyjemny nawyk, niechciana reakcja emocjonalna, zachowanie w konkretnej sytuacji, cokolwiek.

Poniżej kilka przykładów rzeczy, z którymi możesz pracować za pomocą Swish Pattern: — obgryzanie paznokci, obgryzanie ust — nawyk strzelania kostkami palców — dłubanie w nosie — tiki nerwowe — nawyk jedzenia słodyczy

— impulsywne, nerwowe reakcje i zachowania

A oto dokładny opis techniki Swish Pattern. Pod spodem znajdziesz graficzne zobrazowanie procesu a także kilka ważnych zasad, które warto poznać przed przystąpieniem do działania. Gdy już więc wybrałeś zachowanie, nawyk lub kompulsję do zmiany, przystąp do wykonania poniższych czynności:

1. Zastanów się, co wywołuje to niechciane zachowanie, które chcesz zmienić. Co jest bodźcem wywołującym tę reakcję? Czy jest to sygnał pochodzący z określonego miejsca w Twoim ciele, dźwięk, określona rzecz, którą widzisz na chwilę przed zachowaniem? Zidentyfikuj bodziec, który poprzedza to zachowanie.

2. Zamknij oczy i zrób duży i wyraźny obraz bodźca. Niech to będzie obraz momentu na chwilę przed zachowaniem, które chcesz zmienić. Obraz ma być jasny i kolorowy.

3. Teraz zastanów się co chciałbyś mieć zamiast tego zachowania. Co byś robił, gdybyś już miał kontrolę nad nim? Stwórz atrakcyjny obraz tego, kim się staniesz i co będziesz robić gdy już pozbędziesz się starego nawyku. Niech ten obraz będzie duży, jasny, kolorowy i ostry. Na tym obrazie powinieneś widzieć siebie z perspektywy obserwatora.

4. Teraz powróć do obrazu bodźca z punktu 2. Zobacz go jasno i wyraźnie. W lewym dolnym rogu tego obrazu umieść mały, przyciemniony obrazek stanu pożądanego z punktu 3.

Совет

5. Nagle zmniejsz i przyciemnij duży obraz bodźca jednocześnie powiększając i rozjaśniając mały obrazek stanu pożądanego. Niech obrazy zamienią się miejscami. Zrób tę zamianę szybko i dodaj tam dźwięk „swish” (świst). Po zamianie powinieneś widzieć duży i jasny obraz pożądany z małym i ciemnym obrazem bodźca w lewym dolnym rogu.

6. Otwórz oczy na kilka sekund, po czym znowu je zamknij. Znów zobacz niechciany obraz jako duży i jasny a stan pożądany jako mały i ciemny obrazek w lewym dolnym rogu. Ponownie zrób szybką zamianę obrazów dodając dźwięk „swish”. Powtórz to jeszcze 5 razy po każdym razie otwierając na kilka sekund oczy.

7. Sprawdź zmianę przywołując obraz bodźca. Jeśli zamiana dokonuje się automatycznie, doskonale. Jeśli nie, powtórz zamianę jeszcze kilka razy lub zmień submodalności, nad którymi pracujesz.

Jak to wygląda w praktyce:

Uwagi odnośnie poszczególnych etapów techniki Swish Pattern:

Ad 1. Sygnały mogą być bardzo różne. Przy obgryzaniu paznokci może to być na przykład widok Twoich palców lub uczucie swędzenia na ich opuszkach. Przy kompulsywnym objadaniu się słodyczami może być to obraz pysznej czekolady. Bodźce mogą być wewnętrzne lub zewnętrzne, związane ze wzrokiem, dźwiękami lub odczuciami. Zastanów się co poprzedza niechciane zachowanie, co je wywołuje.

Ad 2. Na początku ćwiczenia tej techniki być może nie uda Ci się dokonywać szybkiej zamiany obrazów. Nie szkodzi, potrenuj to zaczynając od wolnej i dokładnej zamiany. Z czasem będziesz to robił coraz szybciej.

Najlepiej, aby zamiana obrazów trwała mniej niż sekundę. Dopiero gdy uda Ci się robić to szybko, zacznij proces 5 zamian. Pamiętaj, aby po zamianie nowy, pożądany obraz był duży, jasny, wyraźny i kolorowy. Te submodalności są tutaj kluczowe.

Jeśli jeszcze nie wiesz czym są submodalności, zajrzyj do tego artykułu.

Pamiętaj też, ze zamiana nie ma zachodzić na tej zasadzie, że najpierw pierwszy obraz się zmniejsza i przyciemnia, a dopiero po tym obraz pożądany się powiększa i rozjaśnia – oba procesy mają zajść równocześnie!

Ad 3. Otwieranie oczu po każdej zamianie to bardzo istotny element techniki. Chodzi tutaj o oczyszczenie obrazu, aby proces się nie zapętlił. Inaczej Twój mózg zautomatyzowałby proces nie tylko przechodzenia od stanu niechcianego w pożądany, ale również z powrotem. A my chcemy mieć tylko bilet w jedną stronę.

Ad 4. Efektem dobrze zrobionego swisha jest automatyzacja zmiany obrazów. Wtedy prawdopodobnie nie uda Ci się już wyobrazić sobie obrazu bodźca, bo będzie się on od razu zamieniał w obraz stanu pożądanego.

Jeśli jednak tak się nie stanie, możesz kilka razy powtórzyć zamianę obrazów. Możesz też popracować z innymi submodalnościami, tzn.

Обратите внимание

zamiast wielkości i jasności obrazu wziąć pod uwagę na przykład odległość i ostrość.

Gdy już uda Ci się zmienić jedno zachowanie, weź pod warsztat kolejne i pracuj dalej. Daj znać w komentarzach, co udało Ci się osiągnąć!

O autorze

Паттерн проектирования Приспособленец (Flyweight) на PHP

Паттерн свиш (паттерн мгновенного переноса)

Перед прочтением ознакомьтесь с введением в паттерны проектирования на PHP, в котором описаны принятые соглашения и понятия. Данная статья дополняется с некоторой периодичностью, так что если вы ее читали ранее, не факт что данные не изменились.

Приспособленец (Flyweight) относиться к классу структурных паттернов. Он используется для эффективной поддержки множества мелких объектов.

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

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

И вот наступает тот момент, когда страница грузится  достаточно долго, чтобы мы успели не только заскучать, но и совершить вечерний променад. Мы достигаем точки кипения и с большой неохотой пытаемся оптимизировать нашу архитектуру.

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

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

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

Важно

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

У нас есть набор параметров (артикул подушки, цвет подушки, цена, скидка), которые полностью характеризуют этот товар.

Соответственно, если у нас было несколько покупателей, которые выбрали одну и туже модель подушки, одного и того же цвета и попали под одну и туже скидку, то итоговые объекты-товары будут полностью идентичны.

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

Где:

FlyweightFactory — модифицированный паттерн фабрика, для создания приспособленцев. Методу getFlyweight передаются признаки, по которым будет создан новый, либо найден и возвращен уже готовый объект.

Flyweight — абстрактный класс приспособленцев

ConcreteFlyweight — конкретная реализация приспособленца, которая будет замещать собой одинаковые мелкие объекты.

UnsharedFlyweight — реализация приспособленца, который не может быть разделен.

class FlyweightFactory
{ protected static $_flyweigths = array(); /** * @param string $key * @return Flyweight */ public static function getFlyweight($key) { // key может быть не только строкой, но и любым другим типом, // в таком случае необходим иной способ поиска созданных приспособленцев if (! isset(self::$_flyweigths[$key])) { // здесь могут быть условия, когда создавать обычного приспособленца, // а когда возвращать неделимого self::$_flyweigths[$key] = new ConcreteFlyweight(); } return self::$_flyweigths[$key]; }
} abstract class Flyweight
{ /** * @var mixed внутреннее состояние */ protected $_intrinsicState = null; /** * @param mixed $extrinsicState * внешнее состояние, передаваемое в приспособленец (контекст) */ public function Operation($extrinsicState) { //…. }
} class ConcreteFlyweight extends Flyweight {}
class UnsharedFlyweight extends Flyweight {}

Скачать исходный код можно тут.

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

Паттерн MVC на примере Cапера — IT Notes

Паттерн свиш (паттерн мгновенного переноса)

Паттерн Model-View-Controller (MVC) является крайне полезным при создании приложений со сложным графическим интерфейсом или поведением. Но и для более простых случаев он также подойдет.

В этой заметке мы создадим игру сапер, спроектированную на основе этого паттерна. В качестве языка разработки выбран Python, однако особого значения в этом нет.

Паттерны не зависят от конкретного языка программирования и вы без труда сможете перенести получившуюся реализацию на любую другую платформу.

Реклама

Коротко о паттерне MVC

Как следует из названия, паттерн MVC включает в себя 3 компонента: Модель, Представление и Контроллер. Каждый из компонентов выполняет свою роль и является взаимозаменяемым.

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

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

Модель

Отвечает за внутреннюю логику работы программы. Здесь мы можем скрыть способы хранения данных, а также правила и алгоритмы обработки информации.

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

Представление

Отвечает за отображение данных Модели. На этом уровне мы лишь предоставляем интерфейс для взаимодействия пользователя с Моделью. Смысл введения этого компонента тот же, что и в случае с предоставлением различных способов хранения данных на основе нескольких Моделей.

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

Кроме того, следует учитывать, что в обязанности Представления входит лишь своевременное отображение состояния Модели. За обработку действий пользователя отвечает Контроллер, о которым мы сейчас и поговорим.

Контроллер

Обеспечивает связь между Моделью и действиями пользователя, полученными в результате взаимодействия с Представлением. Координирует моменты обновления состояний Модели и Представления. Принимает большинство решений о переходах приложения из одного состояния в другое.

Фактически на каждое действие, которое может сделать пользователь в Представлении, должен быть определен обработчик в Контроллере. Этот обработчик выполнит соответствующие манипуляции над моделью и в случае необходимости сообщит Представлению о наличии изменений.

Реклама

Спецификации игры Сапер

Достаточно теории. Теперь перейдем к практике. Для демонстрации паттерна MVC мы напишем несложную игру: Сапер. Правила игры достаточно простые:

  1. Игровое поле представляет собой прямоугольную область, состоящую из клеток. В некоторых клетках случайным образом расположены мины, но игрок о них не знает;
  2. Игрок может щелкнуть по любой клетке игрового поля левой или правой кнопками мыши;
  3. Щелчок левой кнопки мыши приводит к тому, что клетка будет открыта. При этом, если в клетке находится мина, то игра завершается проигрышем. Если в соседних клетках, рядом с открытой, расположены мины, то на открытой клетке отобразится счетчик с числом мин вокруг. Если же мин вокруг открытой клетки нет, то каждая соседняя клетка будет открыта по тому же принципу. То есть клетки будут открываться до тех пор, пока либо не упрутся в границу игрового поля, либо не дойдут до уже открытых клеток, либо рядом с ними не окажется мина;
  4. Щелчок правой кнопки мыши позволяет делать пометки на клетках. Щелчок на закрытой клетке помечает ее флажком, который блокирует ее состояние и предотвращает случайное открытие. Щелчок на клетке, помеченной флажком, меняет ее пометку на вопросительный знак. В этом случае клетка уже не блокируется и может быть открыта левой кнопкой мыши. Щелчок на клетке с вопросительным знаком возвращает ей закрытое состояние без пометок;
  5. Победа определяется состоянием игры, при котором на игровом поле открыты все клетки, за исключением заминированных.

Пример того, что у нас получится приведен ниже:

UML-диаграммы игры Сапер

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

Диаграмма Состояний игровой клетки

Любая клетка на игровом поле может находиться в одном из 4 состояний:

  1. Клетка закрыта;
  2. Клетка открыта;
  3. Клетка помечена флажком;
  4. Клетка помечена вопросительным знаком.

Здесь мы определили лишь состояния, значимые для Представления. Поскольку мины в процессе игры не отображаются, то и в базовом наборе соответствующего состояния не предусмотрено. Определим возможные переходы из одного состояния клетки в другое с помощью UML Диаграммы Состояний:

Диаграмма Классов игры Сапер

Поскольку мы решили создавать наше приложение на основе паттерна MVC, то у нас будет три основных класса: MinesweeperModel, MinesweeperView и MinesweeperController, а также вспомогательный класс MinesweeperCell для хранения состояния клетки. Рассмотрим их диаграмму классов:

Организация архитектуры довольно проста. Здесь мы просто распределили задачи по каждому классу в соответствии с принципами паттерна MVC:

  1. В самом низу иерархии расположен класс игровой клетки MinesweeperCell. Он хранит позицию клетки, определяемую рядом row и столбцом column игрового поля; одно из состояний state, которые мы описали в предыдущем подразделе; информацию о наличии мины в клетке (mined) и счетчик мин в соседних клетках counter. Кроме того, у него есть два метода: nextMark() для циклического перехода по состояниям, связанным с пометками, появляющимися в результате щелчка правой кнопкой мыши, а также open(), который обрабатывает событие, связанное с щелчком левой кнопкой мыши;
  2. Чуть выше расположен класс Модели MinesweeperModel. Он является контейнером для игровых клеток MinesweeperCell. Его первый метод startGame() подготавливает игровое поле для начала игры. Метод isWin() делает проверку игрового поля на состояние выигрыша и возвращает истину, если игрок победил, иначе возвращается ложь. Для проверки проигрыша предназначен аналогичный метод isGameOver(). Методы openCell() и nextCellMark() всего лишь делегируют действия соответствующим клеткам на игровом поле, а метод getCell() возвращает запрашиваемую игровую клетку;
  3. Класс Представления MinesweeperView включает следующие методы: syncWithModel() — обеспечивает перерисовку Представления для отображения актуального состояния игрового поля в Модели; getGameSettings() — возвращает настройки игры, заданные пользователем; createBoard() — создает игровое поле на основе данных Модели; showWinMessage() и showGameOverMessage() соответственно отображают сообщения о победе и проигрыше;
  4. И наконец класс Контроллера MinesweeperController. В нем определено всего три метода на каждое возможное действие игрока: startNewGame() отвечает за нажатие на кнопке «Новая игра» в интерфейсе Представления; onLeftClick() и onRightClick() обрабатывают щелчки по игровым клеткам левой и правой кнопками мыши соответственно.

Реализация игры Сапер на Python

Пришло время заняться реализацией нашего проекта. В качестве языка разработки выберем Python. Тогда класс Представления будем писать на основе модуля tkinter.

Но начнем с Модели.

Модель MinsweeperModel

Реализация модели на языке Python выглядит следующим образом:

MIN_ROW_COUNT = 5 MAX_ROW_COUNT = 30 MIN_COLUMN_COUNT = 5 MAX_COLUMN_COUNT = 30 MIN_MINE_COUNT = 1 MAX_MINE_COUNT = 800 class MinesweeperCell: # Возможные состояния игровой клетки: # closed — закрыта # opened — открыта # flagged — помечена флажком # questioned — помечена вопросительным знаком def __init__( self, row, column ): self.row = row self.column = column self.state = 'closed' self.mined = False self.counter = 0 markSequence = [ 'closed', 'flagged', 'questioned' ] def nextMark( self ): if self.state in self.markSequence: stateIndex = self.markSequence.index( self.state ) self.state = self.markSequence[ ( stateIndex + 1 ) % len( self.markSequence ) ] def open( self ): if self.state != 'flagged': self.state = 'opened' class MinesweeperModel: def __init__( self ): self.startGame() def startGame( self, rowCount = 15, columnCount = 15, mineCount = 15 ): if rowCount in range( MIN_ROW_COUNT, MAX_ROW_COUNT + 1 ): self.rowCount = rowCount if columnCount in range( MIN_COLUMN_COUNT, MAX_COLUMN_COUNT + 1 ): self.columnCount = columnCount if mineCount < self.rowCount * self.columnCount: if mineCount in range( MIN_MINE_COUNT, MAX_MINE_COUNT + 1 ): self.mineCount = mineCount else: self.mineCount = self.rowCount * self.columnCount - 1 self.firstStep = True self.gameOver = False self.cellsTable = [] for row in range( self.rowCount ): cellsRow = [] for column in range( self.columnCount ): cellsRow.append( MinesweeperCell( row, column ) ) self.cellsTable.append( cellsRow ) def getCell( self, row, column ): if row < 0 or column < 0 or self.rowCount

Сохраняем бесшовный узор в панели Swatches в формате EPS10

Паттерн свиш (паттерн мгновенного переноса)

Многие из вас, наверное, замечали, что образец бесшовного паттерна в большинстве случаев исчезает из панели Swatches, после того, как вы сохраните файл в формате eps10.

Это не большая проблема, но если заботиться о клиенте и рассчитывать на длительное сотрудничество, об этом стоит задуматься. Кроме того, некоторые стоки требуют сохранять образец бесшовного паттерна (это Graphicriver, по-моему).

Давайте изучим проблему и постараемся ее решить.

Максимально допустимый формат векторного файла для стоков это eps10, который соответствует функционалу Adobe Illustrator10 (2001 год).

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

Мое небольшое исследование выявило такие объекты. Итак, список объектов, которые не сохраняются ни при каких условиях в панели Swatches:

  • Обтравочная маска
  • Маска прозрачности
  • Градиентная заливка
  • Градиентная сетка
  • Градиент на обводке

А вот список объектов, которые без проблем сохраняются в панели Swatches формата eps10:

  • Плоская заливка
  • Обводка равномерная и переменной ширины
  • Пути, к которым применены кисти
  • Объекты с прозрачностями
  • Envelope Distort объекты

Даже если вы используете эти “разрешенные” объекты, вы не застрахованы от того, что образец не будет сохранен.

Просто, если вы использовали для создания бесшовного паттерна новую функцию Pattern Maker (Ai CS6-CC18), то в большинстве случаев образец исчезнет из панели Swatches.

Конечно, вы можете создавать паттерн при помощи этого удобного инструмента, но вот подготовить паттерн придется особым образом:

Совет

Вытащите паттерн из панели Swatches на рабочую область. Теперь образец из панели может быть удален.

Избавьтесь от всех обтравочных масок (Object > Clipping Mask > Release (Alt+Ctrl+7)). Удалите clipping path.

Максимально разгруппируйте все объекты. Автоматическая группировка при помощи функции Pattern Maker, также может привести к исчезновению образца паттерна.

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

Группируем все объекты (не обязательно, просто мне так спокойней) и перетаскиваем группу назад в панель Swatches.

Теперь попробуем сохранить файл в формате eps10. Вуаля! Образец бесшовного узора остался в панели Swatches.

Снимок

Паттерн свиш (паттерн мгновенного переноса)

Также известен как: Хранитель, Memento

Снимок — это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая подробностей их реализации.

Предположим, что вы пишете программу текстового редактора. Помимо обычного редактирования, ваш редактор позволяет менять форматирование текста, вставлять картинки и прочее.

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

Перед выполнением команды вы можете сохранить копию состояния редактора, чтобы потом иметь возможность отменить операцию.

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

Обратите внимание

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

Как команде создать снимок состояния редактора, если все его поля приватные?

Но это ещё не все. Давайте теперь рассмотрим сами копии состояния редактора.

Из чего состоит состояние редактора? Даже самый примитивный редактор должен иметь несколько полей для хранения текущего текста, позиции курсора и прокрутки экрана.

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

Скорее всего, вам понадобится хранить массу таких контейнеров в качестве истории операций, поэтому удобнее всего сделать их объектами одного класса. Этот класс должен иметь много полей, но практически никаких методов.

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

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

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

Все проблемы, описанные выше, возникают из-за нарушения инкапсуляции. Это когда одни объекты пытаются сделать работу за других, влезая в их приватную зону, чтобы собрать необходимые для операции данные.

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

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

Снимок полностью открыт для создателя, но лишь частично открыт для опекунов.

Такая схема позволяет создателям производить снимки и отдавать их для хранения другим объектам, называемым опекунами.

Опекунам будет доступен только ограниченный интерфейс снимка, поэтому они никак не смогут повлиять на «внутренности» самого снимка.

Важно

В нужный момент опекун может попросить создателя восстановить своё состояние, передав ему соответствующий снимок.

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

Классическая реализация паттерна полагается на механизм вложенных классов, который доступен лишь в некоторых языках программирования (C++, C#, Java).

  1. Создатель может производить снимки своего состояния, а также воспроизводить прошлое состояние, если подать в него готовый снимок.

  2. Снимок — это простой объект данных, содержащий состояние создателя. Надёжнее всего сделать объекты снимков неизменяемыми, передавая в них состояние только через конструктор.

  3. Опекун должен знать, когда делать снимок создателя и когда его нужно восстанавливать.

    Опекун может хранить историю прошлых состояний создателя в виде стека из снимков. Когда понадобится отменить выполненную операцию, он возьмёт «верхний» снимок из стека и передаст его создателю для восстановления.

  4. В данной реализации снимок — это внутренний класс по отношению к классу создателя. Именно поэтому он имеет полный доступ к полям и методам создателя, даже приватным. С другой стороны, опекун не имеет доступа ни к состоянию, ни к методам снимков и может всего лишь хранить ссылки на эти объекты.

Реализация с пустым промежуточным интерфейсом

Подходит для языков, не имеющих механизма вложенных классов (например, PHP).

  1. В этой реализации создатель работает напрямую с конкретным классом снимка, а опекун — только с его ограниченным интерфейсом.

  2. Благодаря этому достигается тот же эффект, что и в классической реализации. Создатель имеет полный доступ к снимку, а опекун — нет.

Снимки с повышенной защитой

Когда нужно полностью исключить возможность доступа к состоянию создателей и снимков.

  1. Эта реализация разрешает иметь несколько видов создателей и снимков. Каждому классу создателей соответствует свой класс снимков. Ни создатели, ни снимки не позволяют другим объектам прочесть своё состояние.

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

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

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

Пример сохранения снимков состояния текстового редактора.

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

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

// Класс создателя должен иметь специальный метод, который
// сохраняет состояние создателя в новом объекте-снимке.
class Editor is private field text, curX, curY, selectionWidth method setText(text) is this.text = text method setCursor(x, y) is this.curX = curX this.curY = curY method setSelectionWidth(width) is this.selectionWidth = width method createSnapshot():Snapshot is // Снимок — неизменяемый объект, поэтому Создатель // передаёт все своё состояние через параметры // конструктора. return new Snapshot(this, text, curX, curY, selectionWidth) // Снимок хранит прошлое состояние редактора.
class Snapshot is private field editor: Editor private field text, curX, curY, selectionWidth constructor Snapshot(editor, text, curX, curY, selectionWidth) is this.editor = editor this.text = text this.curX = curX this.curY = curY this.selectionWidth = selectionWidth // В нужный момент владелец снимка может восстановить // состояние редактора. method restore() is editor.setText(text) editor.setCursor(curX, curY) editor.setSelectionWidth(selectionWidth) // Опекуном может выступать класс команд (см. паттерн Команда).
// В этом случае команда сохраняет снимок состояния объекта-
// получателя, перед тем как передать ему своё действие. А в
// случае отмены команда вернёт объект в прежнее состояние.
class Command is private field backup: Snapshot method makeBackup() is backup = editor.createSnapshot() method undo() is if (backup != null) backup.restore() // …

Когда вам нужно сохранять мгновенные снимки состояния объекта (или его части), чтобы впоследствии объект можно было восстановить в том же состоянии.

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

Когда прямое получение состояния объекта раскрывает приватные детали его реализации, нарушая инкапсуляцию.

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

  1. Определите класс создателя, объекты которого должны создавать снимки своего состояния.

  2. Создайте класс снимка и опишите в нём все те же поля, которые имеются в оригинальном классе-создателе.

  3. Сделайте объекты снимков неизменяемыми. Они должны получать начальные значения только один раз, через свой конструктор.

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

  5. Добавьте в класс создателя метод получения снимков. Создатель должен создавать новые объекты снимков, передавая значения своих полей через конструктор.

    Сигнатура метода должна возвращать снимки через ограниченный интерфейс, если он у вас есть. Сам класс должен работать с конкретным классом снимка.

  6. Добавьте в класс создателя метод восстановления из снимка. Что касается привязки к типам, руководствуйтесь той же логикой, что и в пункте 4.

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

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

  • Не нарушает инкапсуляции исходного объекта.
  • Упрощает структуру исходного объекта. Ему не нужно хранить историю версий своего состояния.
  • Требует много памяти, если клиенты слишком часто создают снимки.
  • Может повлечь дополнительные издержки памяти, если объекты, хранящие историю, не освобождают ресурсы, занятые устаревшими снимками.
  • В некоторых языках (например, PHP, Python, JavaScript) сложно гарантировать, чтобы только исходный объект имел доступ к состоянию снимка.
  • Команду и Снимок можно использовать сообща для реализации отмены операций. В этом случае объекты команд будут отвечать за выполнение действия над объектом, а снимки будут хранить резервную копию состояния этого объекта, сделанную перед самым запуском команды.

  • Снимок можно использовать вместе с Итератором, чтобы сохранить текущее состояние обхода структуры данных и вернуться к нему в будущем, если потребуется.

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

Поделиться новостью