Презентация Iterator Mediator Momento Observer State. Назначение паттерна Iterator онлайн
На нашем сайте вы можете скачать и просмотреть онлайн доклад-презентацию на тему Iterator Mediator Momento Observer State. Назначение паттерна Iterator абсолютно бесплатно. Урок-презентация на эту тему содержит всего 76 слайдов. Все материалы созданы в программе PowerPoint и имеют формат ppt или же pptx. Материалы и темы для презентаций взяты из открытых источников и загружены их авторами, за качество и достоверность информации в них администрация сайта не отвечает, все права принадлежат их создателям. Если вы нашли то, что искали, отблагодарите авторов - поделитесь ссылкой в социальных сетях, а наш сайт добавьте в закладки.
Презентации » Устройства и комплектующие » Iterator Mediator Momento Observer State. Назначение паттерна Iterator
Оцените!
Оцените презентацию от 1 до 5 баллов!
- Тип файла:ppt / pptx (powerpoint)
- Всего слайдов:76 слайдов
- Для класса:1,2,3,4,5,6,7,8,9,10,11
- Размер файла:366.86 kB
- Просмотров:108
- Скачиваний:0
- Автор:неизвестен
Слайды и текст к этой презентации:
№3 слайд
![Назначение паттерна Iterator](/documents_6/7b27c719721e5e21cdea76e797c081b2/img2.jpg)
Содержание слайда: Назначение паттерна Iterator
Предоставляет способ последовательного доступа ко всем элементам составного объекта, не раскрывая его внутреннего представления.
Абстракция в стандартных библиотеках C++ и Java, позволяющая разделить классы коллекций и алгоритмов.
Придает обходу коллекции "объектно-ориентированный статус".
№5 слайд
![Составной объект, такой как](/documents_6/7b27c719721e5e21cdea76e797c081b2/img4.jpg)
Содержание слайда: Составной объект, такой как список, должен предоставлять способ доступа к его элементам без раскрытия своей внутренней структуры. Более того, иногда нужно перебирать элементы списка различными способами, в зависимости от конкретной задачи. Но вы, вероятно, не хотите раздувать интерфейс списка операциями для различных обходов, даже если они необходимы. Кроме того, иногда нужно иметь несколько активных обходов одного списка одновременно. Было бы хорошо иметь единый интерфейс для обхода разных типов составных объектов (т.е. полиморфная итерация).
№6 слайд
![Ключевая идея состоит в том,](/documents_6/7b27c719721e5e21cdea76e797c081b2/img5.jpg)
Содержание слайда: Ключевая идея состоит в том, чтобы ответственность за доступ и обход переместить из составного объекта на объект Iterator, который будет определять стандартный протокол обхода.
Абстракция Iterator имеет основополагающее значение для технологии, называемой "обобщенное программирование". Эта технология четко разделяет такие понятия как "алгоритм" и "структура данных".
Мотивирующие факторы: способствование компонентной разработке, повышение производительности и снижение расходов на управление.
№7 слайд
![Если вы хотите одновременно](/documents_6/7b27c719721e5e21cdea76e797c081b2/img6.jpg)
Содержание слайда: Если вы хотите одновременно поддерживать четыре вида структур данных (массив, бинарное дерево, связанный список и хэш-таблица) и три алгоритма (сортировка, поиск и слияние), то традиционный подход потребует 12 вариантов конфигураций (четыре раза по три), в то время как обобщенное программирование требует лишь 7 (четыре плюс три).
№8 слайд
![Когда использовать итераторы?](/documents_6/7b27c719721e5e21cdea76e797c081b2/img7.jpg)
Содержание слайда: Когда использовать итераторы?
Когда необходимо осуществить обход объекта без раскрытия его внутренней структуры
Когда имеется набор составных объектов, и надо обеспечить единый интерфейс для их перебора
Когда необходимо предоставить несколько альтернативных вариантов перебора одного и того же объекта
№10 слайд
![Участники Iterator определяет](/documents_6/7b27c719721e5e21cdea76e797c081b2/img9.jpg)
Содержание слайда: Участники
Iterator: определяет интерфейс для обхода составных объектов
Aggregate: определяет интерфейс для создания объекта-итератора
ConcreteIterator: конкретная реализация итератора для обхода объекта Aggregate.
ConcreteAggregate: конкретная реализация Aggregate. Хранит элементы, которые надо будет перебирать
Client: использует объект Aggregate и итератор для его обхода
№12 слайд
![у нас есть класс читателя,](/documents_6/7b27c719721e5e21cdea76e797c081b2/img11.jpg)
Содержание слайда: у нас есть класс читателя, который хочет получить информацию о книгах, которые находятся в библиотеке. И для этого надо осуществить перебор объектов с помощью итератора:
class Program
{
static void Main(string[] args)
{
Library library = new Library();
Reader reader = new Reader();
reader.SeeBooks(library);
Console.Read();
}
}
class Reader
{
public void SeeBooks(Library library)
{
IBookIterator iterator = library.CreateNumerator();
while(iterator.HasNext())
{
Book book = iterator.Next();
Console.WriteLine(book.Name);
}
}
}
interface IBookIterator
{
bool HasNext();
Book Next();
}
interface IBookNumerable
{
IBookIterator CreateNumerator();
int Count { get; }
Book this[int index] { get;}
}
class Book
{
public string Name { get; set; }
}
class Library : IBookNumerable
{
private Book[] books;
public Library()
{
books = new Book[]
{
new Book{Name="Война и мир"},
new Book {Name="Отцы и дети"},
new Book {Name="Вишневый сад"}
};
}
public int Count
{
get { return books.Length; }
}
public Book this[int index]
{
get { return books[index]; }
}
public IBookIterator CreateNumerator()
{
return new LibraryNumerator(this);
}
}
class LibraryNumerator : IBookIterator
{
IBookNumerable aggregate;
int index=0;
public LibraryNumerator(IBookNumerable a)
{
aggregate = a;
}
public bool HasNext()
{
return index<aggregate.Count;
}
public Book Next()
{
return aggregate[index++];
}
}
№14 слайд
![. Назначение экземпляра](/documents_6/7b27c719721e5e21cdea76e797c081b2/img13.jpg)
Содержание слайда: 1. Назначение экземпляра класса ConcreteAggregate - хранить элементы, которые надо будет перебирать.
2. Назначение экземпляра класса ConcreteIterator - реализация итератора для обхода объекта класса Aggregate
3. Иначе говоря, итератор у нас реализуется объектом класса ConcreteIterator, а не объектом классаConcreteAggregate - который используется только как хранилище объектов для перебора.
4. Объект же класса ConcreteAggregate только передается в качестве агрегата в объект класса ConcreteIterator как хранилище объектов - и не более того.
№16 слайд
![Назначение паттерна Mediator](/documents_6/7b27c719721e5e21cdea76e797c081b2/img15.jpg)
Содержание слайда: Назначение паттерна Mediator
Mediator делает систему слабо связанной, избавляя объекты от необходимости ссылаться друг на друга, что позволяет изменять взаимодействие между ними независимо.
Паттерн Mediator вводит посредника для развязывания множества взаимодействующих объектов.
Заменяет взаимодействие "все со всеми" взаимодействием "один со всеми".
№17 слайд
![Решаемая проблема Мы хотим](/documents_6/7b27c719721e5e21cdea76e797c081b2/img16.jpg)
Содержание слайда: Решаемая проблема
Мы хотим спроектировать систему с повторно используемыми компонентами, однако существующие связи между этими компонентами можно охарактеризовать феноменом "спагетти-кода".
Спагетти-код - плохо спроектированная, слабо структурированная, запутанная и трудная для понимания программа. Спагетти-код назван так, потому что ход выполнения программы похож на миску спагетти, то есть извилистый и запутанный.
№18 слайд
![В Unix права доступа к](/documents_6/7b27c719721e5e21cdea76e797c081b2/img17.jpg)
Содержание слайда: В Unix права доступа к системным ресурсам определяются тремя уровнями: владелец, группа и прочие. Группа представляет собой совокупность пользователей, обладающих некоторой функциональной принадлежностью. Каждый пользователь в системе может быть членом одной или нескольких групп, и каждая группа может иметь 0 или более пользователей, назначенных этой группе. Следующий рисунок показывает трех пользователей, являющихся членами всех трех групп.
Если нам нужно было бы построить программную модель такой системы, то мы могли бы связать каждый объект User c каждым объектом Group, а каждый объект Group - с каждым объектом User. Однако из-за наличия множества взаимосвязей модифицировать поведение такой системы очень непросто, пришлось бы изменять все существующие классы.
Альтернативный подход - введение "дополнительного уровня косвенности" или построение абстракции из отображения (соответствия) пользователей в группы и групп в пользователей. Такой подход обладает следующими преимуществами: пользователи и группы отделены друг от друга, отображениями легко управлять одновременно и абстракция отображения может быть расширена в будущем путем определения производных классов.
Разбиение системы на множество объектов в общем случае повышает степень повторного использования, однако множество взаимосвязей между этими объектами, как правило, приводит к обратному эффекту. Чтобы этого не допустить, инкапсулируйте взаимодействия между объектами в объект-посредник. Действуя как центр связи, этот объект-посредник контролирует и координирует взаимодействие группы объектов. При этом объект-посредник делает взаимодействующие объекты слабо связанными, так как им больше не нужно хранить ссылки друг на друга – все взаимодействие идет через этого посредника. Расширить или изменить это взаимодействие можно через его подклассы.
Паттерн Mediator заменяет взаимодействие "все со всеми" взаимодействием "один со всеми".
Пример рационального использования паттерна Mediator – моделирование отношений между пользователями и группами операционной системы. Группа может иметь 0 или более пользователей, а пользователь может быть членом 0 или более групп. Паттерн Mediator предусматривает гибкий способ управления пользователями и группами.
№20 слайд
![Участники Mediator](/documents_6/7b27c719721e5e21cdea76e797c081b2/img19.jpg)
Содержание слайда: Участники
Mediator: представляет интерфейс для взаимодействия с объектами Colleague
Colleague: представляет интерфейс для взаимодействия с объектом Mediator
ConcreteColleague1 и ConcreteColleague2: конкретные классы коллег, которые обмениваются друг с другом через объект Mediator
ConcreteMediator: конкретный посредник, реализующий интерфейс типа Mediator
№22 слайд
![Пример паттерна Mediator](/documents_6/7b27c719721e5e21cdea76e797c081b2/img21.jpg)
Содержание слайда: Пример паттерна Mediator
Пример паттерна Mediator
Паттерн Mediator определяет объект, управляющий набором взаимодействующих объектов. Слабая связанность достигается благодаря тому, что вместо непосредственного взаимодействия друг с другом коллеги общаются через объект-посредник.
Башня управления полетами в аэропорту хорошо демонстрирует этот паттерн. Пилоты взлетающих или идущих на посадку самолетов в районе аэропорта общаются с башней вместо непосредственного общения друг с другом. Башня определяет, кто и в каком порядке будет садиться или взлетать. Важно отметить, что башня контролирует самолеты только в районе аэродрома, а не на протяжении всего полета.
№23 слайд
![Пример Система создания](/documents_6/7b27c719721e5e21cdea76e797c081b2/img22.jpg)
Содержание слайда: Пример
Система создания программных продуктов включает ряд акторов: заказчики, программисты, тестировщики и так далее.
Но нередко все эти акторы взаимодействуют между собой не непосредственно, а опосредованно через менеджера проектов. То есть менеджер проектов выполняет роль посредника. В этом случае процесс взаимодействия между объектами мы могли бы описать так:
№24 слайд
![class Program class Program](/documents_6/7b27c719721e5e21cdea76e797c081b2/img23.jpg)
Содержание слайда: class Program
class Program
{
static void Main(string[] args)
{
ManagerMediator mediator = new ManagerMediator();
Colleague customer = new CustomerColleague(mediator);
Colleague programmer = new ProgrammerColleague(mediator);
Colleague tester = new TesterColleague(mediator);
mediator.Customer = customer;
mediator.Programmer = programmer;
mediator.Tester = tester;
customer.Send("Есть заказ, надо сделать программу");
programmer.Send("Программа готова, надо протестировать");
tester.Send("Программа протестирована и готова к продаже");
Console.Read();
}
}
abstract class Mediator
{
public abstract void Send(string msg, Colleague colleague);
}
abstract class Colleague
{
protected Mediator mediator;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
public virtual void Send(string message)
{
mediator.Send(message, this);
}
public abstract void Notify(string message);
}
// класс заказчика
class CustomerColleague : Colleague
{
public CustomerColleague(Mediator mediator)
: base(mediator)
{ }
public override void Notify(string message)
{
Console.WriteLine("Сообщение заказчику: " + message);
}
}
// класс программиста
class ProgrammerColleague : Colleague
{
public ProgrammerColleague(Mediator mediator)
: base(mediator)
{ }
public override void Notify(string message)
{
Console.WriteLine("Сообщение программисту: " + message);
}
}
// класс тестера
class TesterColleague : Colleague
{
public TesterColleague(Mediator mediator)
: base(mediator)
{ }
public override void Notify(string message)
{
Console.WriteLine("Сообщение тестеру: " + message);
}
}
class ManagerMediator : Mediator
{
public Colleague Customer { get; set; }
public Colleague Programmer { get; set; }
public Colleague Tester { get; set; }
public override void Send(string msg, Colleague colleague)
{
// если отправитель - заказчик, значит есть новый заказ
// отправляем сообщение программисту - выполнить заказ
if (Customer == colleague)
Programmer.Notify(msg);
// если отправитель - программист, то можно приступать к тестированию
// отправляем сообщение тестеру
else if (Programmer == colleague)
Tester.Notify(msg);
// если отправитель - тест, значит продукт готов
// отправляем сообщение заказчику
else if (Tester == colleague)
Customer.Notify(msg);
}
}
№27 слайд
![В итоге применение паттерна](/documents_6/7b27c719721e5e21cdea76e797c081b2/img26.jpg)
Содержание слайда: В итоге применение паттерна Посредник дает нам следующие преимущества:
Устраняется сильная связанность между объектами Colleague
Упрощается взаимодействие между объектами: вместо связей по типу "все-ко-всем" применяется связь "один-ко-всем"
Взаимодействие между объектами абстрагируется и выносится в отдельный интерфейс
Централизуется управления отношениями между объектами
№28 слайд
![Использование паттерна](/documents_6/7b27c719721e5e21cdea76e797c081b2/img27.jpg)
Содержание слайда: Использование паттерна Mediator
Определите совокупность взаимодействующих объектов, связанность между которыми нужно уменьшить.
Инкапсулируйте все взаимодействия в абстракцию нового класса.
Создайте экземпляр этого нового класса. Объекты-коллеги для взаимодействия друг с другом используют только этот объект.
Найдите правильный баланс между принципом слабой связанности и принципом распределения ответственности.
Будьте внимательны и не создавайте объект-"контроллер" вместо объекта-посредника.
№29 слайд
![Особенности паттерна Mediator](/documents_6/7b27c719721e5e21cdea76e797c081b2/img28.jpg)
Содержание слайда: Особенности паттерна Mediator
Паттерны Chain of Responsibility, Command, Mediator и Observer показывают, как можно разделить отправителей и получателей запросов с учетом их особенностей. Chain of Responsibility передает запрос отправителя по цепочке потенциальных получателей. Command номинально определяет связь - "оправитель-получатель" с помощью подкласса. В Mediator отправитель и получатель ссылаются друг на друга косвенно, через объект-посредник. В паттерне Observer связь между отправителем и получателем слабее, при этом число получателей может конфигурироваться во время выполнения.
Mediator и Observer являются конкурирующими паттернами. Если Observer распределяет взаимодействие c помощью объектов "наблюдатель" и "субъект", то Mediator использует объект-посредник для инкапсуляции взаимодействия между другими объектами. Мы обнаружили, что легче сделать повторно используемыми Наблюдателей и Субъектов, чем Посредников.
С другой стороны, Mediator может использовать Observer для динамической регистрации коллег и их взаимодействия с посредником.
Mediator похож Faсade в том, что он абстрагирует функциональность существующих классов. Mediator абстрагирует/централизует взаимодействие между объектами-коллегами, добавляет новую функциональность и известен всем объектам-коллегам (то есть определяет двунаправленный протокол взаимодействия). Facade, наоборот, определяет более простой интерфейс к подсистеме, не добавляя новой функциональности, и неизвестен классам подсистемы (то есть имеет однонаправленный протокол взаимодействия, то есть запросы отправляются в подсистему, но не наоборот).
№31 слайд
![Назначение паттерна Memento](/documents_6/7b27c719721e5e21cdea76e797c081b2/img30.jpg)
Содержание слайда: Назначение паттерна Memento
Не нарушая инкапсуляции, паттерн Memento получает и сохраняет за пределами объекта его внутреннее состояние так, чтобы позже можно было восстановить объект в таком же состоянии.
Является средством для инкапсуляции "контрольных точек" программы.
Паттерн Memento придает операциям "Отмена" (undo) или "Откат" (rollback) статус "полноценного объекта".
№33 слайд
![Клиент запрашивает Memento](/documents_6/7b27c719721e5e21cdea76e797c081b2/img32.jpg)
Содержание слайда: Клиент запрашивает Memento (хранителя) у исходного объекта, когда ему необходимо сохранить состояние исходного объекта (установить контрольную точку). Исходный объект инициализирует Memento своим текущим состоянием. Клиент является "посыльным" за Memento, но только исходный объект может сохранять и извлекать информацию из Memento (Memento является "непрозрачным" для клиентов и других объектов). Если клиенту в дальнейшем нужно "откатить" состояние исходного объекта, он передает Memento обратно в исходный объект для его восстановления.
Реализовать возможность выполнения неограниченного числа операций "Отмена" (undo) и "Повтор" (redo) можно с помощью стека объектов Command и стека объектов Memento.
№34 слайд
![Паттерн проектирования](/documents_6/7b27c719721e5e21cdea76e797c081b2/img33.jpg)
Содержание слайда: Паттерн проектирования Memento определяет трех различных участников:
Originator (хозяин) - объект, умеющий создавать хранителя, а также знающий, как восстановить свое внутреннее состояние из хранителя.
Caretaker (смотритель) - объект, который знает, почему и когда хозяин должен сохранять и восстанавливать себя.
Memento (хранитель) - "ящик на замке", который пишется и читается хозяином и за которым присматривает смотритель.
№36 слайд
![Пример паттерна Memento](/documents_6/7b27c719721e5e21cdea76e797c081b2/img35.jpg)
Содержание слайда: Пример паттерна Memento
Паттерн Memento фиксирует и сохраняет за пределами объекта его внутреннее состояние так, чтобы позже этот объект можно было бы восстановить в таком же состоянии.
Этот паттерн часто используется механиками-любителями для ремонта барабанных тормозов на своих автомобилях.
Барабаны удаляются с обеих сторон, чтобы сделать видимыми правые и левые тормоза. При этом разбирается только одна сторона, другая же служит напоминанием (Memento) о том, как части тормозной системы тормозной системы собраны вместе. Только после того, как завершена работа с одной стороны, разбирается другая сторона. При этом в качестве Memento выступает уже первая сторона.
№38 слайд
![Использование паттерна](/documents_6/7b27c719721e5e21cdea76e797c081b2/img37.jpg)
Содержание слайда: Использование паттерна Memento
Определите роли "смотрителя" и "хозяина".
Создайте класс Memento и объявите хозяина другом.
Смотритель знает, когда создавать "контрольную точку" хозяина.
Хозяин создает хранителя Memento и копирует свое состояние в этот Memento.
Смотритель сохраняет хранителя Memento (но смотритель не может заглянуть в Memento).
Смотритель знает, когда нужно "откатить" хозяина.
Хозяин восстанавливает себя, используя сохраненное в Memento состояние.
№39 слайд
![Особенности паттерна Memento](/documents_6/7b27c719721e5e21cdea76e797c081b2/img38.jpg)
Содержание слайда: Особенности паттерна Memento
Паттерны Command и Memento определяют объекты "волшебная палочка", которые передаются от одного владельца к другому и используются позднее. В Command такой "волшебной палочкой" является запрос; в Memento - внутреннее состояние объекта в некоторый момент времени. Полиморфизм важен для Command, но не важен для Memento потому, что интерфейс Memento настолько "узкий", что его можно передавать как значение.
Command может использовать Memento для сохранения состояния, необходимого для выполнения отмены действий.
Memento часто используется совместно с Iterator. Iterator может использовать Memento для сохранения состояния итерации.
№41 слайд
![Участники Memento хранитель,](/documents_6/7b27c719721e5e21cdea76e797c081b2/img40.jpg)
Содержание слайда: Участники
Memento: хранитель, который сохраняет состояние объекта Originator и предоставляет полный доступ только этому объекту Originator
Originator: создает объект хранителя для сохранения своего состояния
Caretaker: выполняет только функцию хранения объекта Memento, в то же время у него нет полного доступа к хранителю и никаких других операций над хранителем, кроме собственно сохранения, он не производит
№43 слайд
![class Program class Program](/documents_6/7b27c719721e5e21cdea76e797c081b2/img42.jpg)
Содержание слайда: class Program
class Program
{
static void Main(string[] args)
{
Hero hero = new Hero();
hero.Shoot(); // делаем выстрел, осталось 9 патронов
GameHistory game = new GameHistory();
game.History.Push(hero.SaveState()); // сохраняем игру
hero.Shoot(); //делаем выстрел, осталось 8 патронов
hero.RestoreState(game.History.Pop());
hero.Shoot(); //делаем выстрел, осталось 8 патронов
Console.Read();
}
}
// Originator
class Hero
{
private int patrons=10; // кол-во патронов
private int lives=5; // кол-во жизней
public void Shoot()
{
if (patrons > 0)
{
patrons--;
Console.WriteLine("Производим выстрел. Осталось {0} патронов", patrons);
}
else
Console.WriteLine("Патронов больше нет");
}
// сохранение состояния
public HeroMemento SaveState()
{
Console.WriteLine("Сохранение игры. Параметры: {0} патронов, {1} жизней", patrons, lives);
return new HeroMemento(patrons, lives);
}
// восстановление состояния
public void RestoreState(HeroMemento memento)
{
this.patrons=memento.Patrons;
this.lives = memento.Lives;
Console.WriteLine("Восстановление игры. Параметры: {0} патронов, {1} жизней", patrons, lives);
}
}
// Memento
class HeroMemento
{
public int Patrons { get; private set; }
public int Lives { get; private set; }
public HeroMemento(int patrons, int lives)
{
this.Patrons = patrons;
this.Lives = lives;
}
}
// Caretaker
class GameHistory
{
public Stack<HeroMemento> History { get; private set; }
public GameHistory()
{
History = new Stack<HeroMemento>();
}
}
№44 слайд
![Консольный вывод программы](/documents_6/7b27c719721e5e21cdea76e797c081b2/img43.jpg)
Содержание слайда: Консольный вывод программы:
Производим выстрел. Осталось 9 патронов
Сохранение игры. Параметры: 9 патронов, 5 жизней
Производим выстрел. Осталось 8 патронов
Восстановление игры. Параметры: 9 патронов, 5 жизней
Производим выстрел. Осталось 8 патронов
Здесь в роли Originator выступает класс Hero, состояние которого описывается количество патронов и жизней. Для хранения состояния игрового персонажа предназначен класс HeroMemento. С помощью метода SaveState() объект Hero может сохранить свое состояние в HeroMemento, а с помощью метода RestoreState() - восстановить.
Для хранения состояний предназначен класс GameHistory, причем все состояния хранятся в стеке, что позволяет с легкостью извлекать последнее сохраненное состояние.
№45 слайд
![Использование паттерна](/documents_6/7b27c719721e5e21cdea76e797c081b2/img44.jpg)
Содержание слайда: Использование паттерна Memento дает нам следующие преимущества:
Уменьшение связанности системы
Сохранение инкапсуляции информации
Определение простого интерфейса для сохранения и восстановления состояния
В то же время мы можем столкнуться с недостатками, в частности, если требуется сохранение большого объема информации, то возрастут издержки на хранение всего объема состояния.
№47 слайд
![Назначение паттерна Observer](/documents_6/7b27c719721e5e21cdea76e797c081b2/img46.jpg)
Содержание слайда: Назначение паттерна Observer
Паттерн Observer определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются и обновляются автоматически.
Паттерн Observer инкапсулирует главный (независимый) компонент в абстракцию Subject и изменяемые (зависимые) компоненты в иерархию Observer.
Паттерн Observer находит широкое применение в системах пользовательского интерфейса, в которых данные и их представления ("виды") отделены друг от друга. При изменении данных должны быть изменены все представления этих данных (например, в виде таблицы, графика и диаграммы).
№48 слайд
![Решаемая проблема Имеется](/documents_6/7b27c719721e5e21cdea76e797c081b2/img47.jpg)
Содержание слайда: Решаемая проблема
Имеется система, состоящая из множества взаимодействующих классов. При этом взаимодействующие объекты должны находиться в согласованных состояниях. Вы хотите избежать монолитности (неразделимости)такой системы, сделав классы слабо связанными (или повторно используемыми).
№49 слайд
![Паттерн Observer определяет](/documents_6/7b27c719721e5e21cdea76e797c081b2/img48.jpg)
Содержание слайда: Паттерн Observer определяет объект Subject, хранящий данные (модель), а всю функциональность "представлений" делегирует слабосвязанным отдельным объектам Observer. При создании наблюдатели Observer регистрируются у объекта Subject. Когда объект Subject изменяется, он извещает об этом всех зарегистрированных наблюдателей. После этого каждый обозреватель запрашивает у объекта Subject ту часть состояния, которая необходима для отображения данных.
Такая схема позволяет динамически настраивать количество и "типы" представлений объектов.
Описанный выше протокол взаимодействия соответствует модели вытягивания (pull), когда субъект информирует наблюдателей о своем изменении, и каждый наблюдатель ответственен за "вытягивание" у Subject нужных ему данных. Существует также модель проталкивания, когда субъект Subject посылает ("проталкивает") наблюдателям детальную информацию о своем изменении.
№50 слайд
![Структура паттерна Observer](/documents_6/7b27c719721e5e21cdea76e797c081b2/img49.jpg)
Содержание слайда: Структура паттерна Observer
Структура паттерна Observer
Subject представляет главную (независимую) абстракцию. Observer представляет изменяемую (зависимую) абстракцию. Субъект извещает наблюдателей о своем изменении, на что каждый наблюдатель может запросить состояние субъекта.
№52 слайд
![Участники IObservable](/documents_6/7b27c719721e5e21cdea76e797c081b2/img51.jpg)
Содержание слайда: Участники
IObservable: представляет наблюдаемый объект. Определяет три метода: AddObserver() (для добавления наблюдателя), RemoveObserver() (удаление набюдателя) и NotifyObservers() (уведомление наблюдателей)
ConcreteObservable: конкретная реализация интерфейса IObservable. Определяет коллекцию объектов наблюдателей.
IObserver: представляет наблюдателя, который подписывается на все уведомления наблюдаемого объекта. Определяет метод Update(), который вызывается наблюдаемым объектом для уведомления наблюдателя.
ConcreteObserver: конкретная реализация интерфейса IObserver.
№53 слайд
![Пример паттерна Observer](/documents_6/7b27c719721e5e21cdea76e797c081b2/img52.jpg)
Содержание слайда: Пример паттерна Observer
Паттерн Observer определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются и обновляются автоматически.
Некоторые аукционы демонстрируют этот паттерн. Каждый участник имеет карточку с цифрами, которую он использует для обозначения предлагаемой цены (ставки). Ведущий аукциона (Subject) начинает торги и наблюдает, когда кто-нибудь поднимает карточку, предлагая новую более высокую цену. Ведущий принимает заявку, о чем тут же извещает всех участников аукциона (Observers).
№55 слайд
![Использование паттерна](/documents_6/7b27c719721e5e21cdea76e797c081b2/img54.jpg)
Содержание слайда: Использование паттерна Observer
Проведите различия между основной (или независимой) и дополнительной (или зависимой) функциональностями.
Смоделируйте "независимую" функциональность с помощью абстракции "субъект".
Смоделируйте "зависимую" функциональность с помощью иерархии "наблюдатель".
Класс Subject связан только c базовым классом Observer.
Клиент настраивает количество и типы наблюдателей.
Наблюдатели регистрируются у субъекта.
Субъект извещает всех зарегистрированных наблюдателей.
Субъект может "протолкнуть" информацию в наблюдателей, или наблюдатели могут "вытянуть" необходимую им информацию от объекта Subject.
№56 слайд
![Особенности паттерна Observer](/documents_6/7b27c719721e5e21cdea76e797c081b2/img55.jpg)
Содержание слайда: Особенности паттерна Observer
Паттерны Chain of Responsibility, Command, Mediator и Observer показывают, как можно разделить отправителей и получателей запросов с учетом своих особенностей. Chain of Responsibility передает запрос отправителя по цепочке потенциальных получателей. Command определяет связь - "оправитель-получатель" с помощью подкласса. В Mediator отправитель и получатель ссылаются друг на друга косвенно, через объект-посредник. В паттерне Observer связь между отправителем и получателем получается слабой, при этом число получателей может конфигурироваться во время выполнения.
Mediator и Observer являются конкурирующими паттернами. Если Observer распределяет взаимодействие c помощью объектов "наблюдатель" и "субъект", то Mediator использует объект-посредник для инкапсуляции взаимодействия между другими объектами. Мы обнаружили, что легче сделать повторно используемыми Наблюдателей и Субъектов, чем Посредников.
Mediator может использовать Observer для динамической регистрации коллег и их взаимодействия с посредником.
№58 слайд
![class Program class Program](/documents_6/7b27c719721e5e21cdea76e797c081b2/img57.jpg)
Содержание слайда: class Program
class Program
{
static void Main(string[] args)
{
Stock stock = new Stock();
Bank bank = new Bank("ЮнитБанк", stock);
Broker broker = new Broker("Иван Иваныч", stock);
// имитация торгов
stock.Market();
// брокер прекращает наблюдать за торгами
broker.StopTrade();
// имитация торгов
stock.Market();
Console.Read();
}
}
interface IObserver
{
void Update(Object ob);
}
interface IObservable
{
void RegisterObserver(IObserver o);
void RemoveObserver(IObserver o);
void NotifyObservers();
}
class Stock : IObservable
{
StockInfo sInfo; // информация о торгах
List<IObserver> observers;
public Stock()
{
observers = new List<IObserver>();
sInfo= new StockInfo();
}
public void RegisterObserver(IObserver o)
{
observers.Add(o);
}
public void RemoveObserver(IObserver o)
{
observers.Remove(o);
}
public void NotifyObservers()
{
foreach(IObserver o in observers)
{
o.Update(sInfo);
}
}
public void Market()
{
Random rnd = new Random();
sInfo.USD = rnd.Next(20, 40);
sInfo.Euro = rnd.Next(30, 50);
NotifyObservers();
}
}
class StockInfo
{
public int USD { get; set; }
public int Euro { get; set; }
}
class Broker : IObserver
{
public string Name { get; set; }
IObservable stock;
public Broker(string name, IObservable obs)
{
this.Name = name;
stock = obs;
stock.RegisterObserver(this);
}
public void Update(object ob)
{
StockInfo sInfo = (StockInfo)ob;
if(sInfo.USD>30)
Console.WriteLine("Брокер {0} продает доллары; Курс доллара: {1}", this.Name, sInfo.USD);
else
Console.WriteLine("Брокер {0} покупает доллары; Курс доллара: {1}", this.Name, sInfo.USD);
}
public void StopTrade()
{
stock.RemoveObserver(this);
stock=null;
}
}
class Bank : IObserver
{
public string Name { get; set; }
IObservable stock;
public Bank(string name, IObservable obs)
{
this.Name = name;
stock = obs;
stock.RegisterObserver(this);
}
public void Update(object ob)
{
StockInfo sInfo = (StockInfo)ob;
if (sInfo.Euro > 40)
Console.WriteLine("Банк {0} продает евро; Курс евро: {1}", this.Name, sInfo.Euro);
else
Console.WriteLine("Банк {0} покупает евро; Курс евро: {1}", this.Name, sInfo.Euro);
}
}
№59 слайд
![Здесь наблюдаемый объект](/documents_6/7b27c719721e5e21cdea76e797c081b2/img58.jpg)
Содержание слайда: Здесь наблюдаемый объект представлен интерфейсом IObservable, а наблюдатель - интерфейсом IObserver. Реализацией интерфейса IObservable является класс Stock, который символизирует валютную биржу. В этом классе определен метод Market(), который имитирует торги и инкапсулирует всю информацию о валютных курсах в объекте StockInfo. После проведения торгов производится уведомление всех наблюдателей.
Здесь наблюдаемый объект представлен интерфейсом IObservable, а наблюдатель - интерфейсом IObserver. Реализацией интерфейса IObservable является класс Stock, который символизирует валютную биржу. В этом классе определен метод Market(), который имитирует торги и инкапсулирует всю информацию о валютных курсах в объекте StockInfo. После проведения торгов производится уведомление всех наблюдателей.
Реализациями интерфейса IObserver являются классы Broker, представляющий брокера, и Bank, представляющий банк. При этом метод Update() интерфейса IObserver принимает в качестве параметра некоторый объект. Реализация этого метода подразумевает получение через данный параметр объекта StockInfo с текущей информацией о торгах и произведение некоторых действий: покупка или продажа долларов и евро. Дело в том, что часто необходимо информировать наблюдателя об изменении состояния наблюдаемого объекта. В данном случае состояние заключено в объекте StockInfo. И одним из вариантом информирования наблюдателя о состоянии является push-модель, при которой наблюдаемый объект передает (иначе говоря толкает - push) данные о своем состоянии, то есть передаем в виде параметра метода Update().
Альтернативой push-модели является pull-модель, когда наблюдатель вытягивает (pull) из наблюдаемого объекта данные о состоянии с помощью дополнительных методов.
Также в классе брокера определен дополнительный метод StopTrade(), с помощью которого брокер может отписаться от уведомлений биржи и перестать быть наблюдателем.
№62 слайд
![Решаемая проблема Поведение](/documents_6/7b27c719721e5e21cdea76e797c081b2/img61.jpg)
Содержание слайда: Решаемая проблема
Поведение объекта зависит от его состояния и должно изменяться во время выполнения программы. Такую схему можно реализовать, применив множество условных операторов: на основе анализа текущего состояния объекта предпринимаются определенные действия.
Однако при большом числе состояний условные операторы будут разбросаны по всему коду, и такую программу будет трудно поддерживать.
№63 слайд
![Паттерн State решает](/documents_6/7b27c719721e5e21cdea76e797c081b2/img62.jpg)
Содержание слайда: Паттерн State решает указанную проблему следующим образом:
Вводит класс Context, в котором определяется интерфейс для внешнего мира.
Вводит абстрактный класс State.
Представляет различные "состояния" конечного автомата в виде подклассов State.
В классе Context имеется указатель на текущее состояние, который изменяется при изменении состояния конечного автомата.
Паттерн State не определяет, где именно определяется условие перехода в новое состояние. Существует два варианта: класс Context или подклассы State. Преимущество последнего варианта заключается в простоте добавления новых производных классов. Недостаток заключается в том, что каждый подкласс State для осуществления перехода в новое состояние должен знать о своих соседях, что вводит зависимости между подклассами.
Существует также альтернативный таблично-ориентированный подход к проектированию конечных автоматов, основанный на использовании таблицы однозначного отображения входных данных на переходы между состояниями. Однако этот подход обладает недостатками: трудно добавить выполнение действий при выполнении переходов. Подход, основанный на использовании паттерна State, для осуществления переходов между состояниями использует код (вместо структур данных), поэтому эти действия легко добавляемы.
№64 слайд
![Структура паттерна State](/documents_6/7b27c719721e5e21cdea76e797c081b2/img63.jpg)
Содержание слайда: Структура паттерна State
Класс Context определяет внешний интерфейс для клиентов и хранит внутри себя ссылку на текущее состояние объекта State. Интерфейс абстрактного базового класса State повторяет интерфейс Context за исключением одного дополнительного параметра - указателя на экземпляр Context. Производные от State классы определяют поведение, специфичное для конкретного состояния. Класс "обертка" Context делегирует все полученные запросы объекту "текущее состояние", который может использовать полученный дополнительный параметр для доступа к экземпляру Context.
№66 слайд
![Участники паттерна State](/documents_6/7b27c719721e5e21cdea76e797c081b2/img65.jpg)
Содержание слайда: Участники паттерна
State: определяет интерфейс состояния
Классы StateA и StateB - конкретные реализации состояний
Context: представляет объект, поведение которого должно динамически изменяться в соответствии с состоянием. Выполнение же конкретных действий делегируется объекту состояния
№67 слайд
![Пример паттерна State Паттерн](/documents_6/7b27c719721e5e21cdea76e797c081b2/img66.jpg)
Содержание слайда: Пример паттерна State
Паттерн State позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Похожая картина может наблюдаться в работе торгового автомата. Автоматы могут иметь различные состояния в зависимости от наличия товаров, суммы полученных монет, возможности размена денег и т.д. После того как покупатель выбрал и оплатил товар, возможны следующие ситуации (состояния):
Выдать покупателю товар, выдавать сдачу не требуется.
Выдать покупателю товар и сдачу.
Покупатель товар не получит из-за отсутствия достаточной суммы денег.
Покупатель товар не получит из-за его отсутствия.
№69 слайд
![Использование паттерна State](/documents_6/7b27c719721e5e21cdea76e797c081b2/img68.jpg)
Содержание слайда: Использование паттерна State
Определите существующий или создайте новый класс-"обертку" Context, который будет использоваться клиентом в качестве "конечного автомата".
Создайте базовый класс State, который повторяет интерфейс класса Context. Каждый метод принимает один дополнительный параметр: экземпляр класса Context. Класс State может определять любое полезное поведение "по умолчанию".
Создайте производные от State классы для всех возможных состояний.
Класс-"обертка" Context имеет ссылку на объект "текущее состояние".
Все полученные от клиента запросы класс Context просто делегирует объекту "текущее состояние", при этом в качестве дополнительного параметра передается адрес объекта Context.
Используя этот адрес, в случае необходимости методы класса State могут изменить "текущее состояние" класса Context.
№70 слайд
![Особенности паттерна State](/documents_6/7b27c719721e5e21cdea76e797c081b2/img69.jpg)
Содержание слайда: Особенности паттерна State
Объекты класса State часто бывают одиночками.
Flyweight показывает, как и когда можно разделять объекты State.
Паттерн Interpreter может использовать State для определения контекстов при синтаксическом разборе.
Паттерны State и Bridge имеют схожие структуры за исключением того, что Bridge допускает иерархию классов-конвертов (аналогов классов-"оберток"), а State-нет. Эти паттерны имеют схожие структуры, но решают разные задачи: State позволяет объекту изменять свое поведение в зависимости от внутреннего состояния, в то время как Bridge разделяет абстракцию от ее реализации так, что их можно изменять независимо друг от друга.
Реализация паттерна State основана на паттерне Strategy. Различия заключаются в их назначении.
№72 слайд
![class Program static void](/documents_6/7b27c719721e5e21cdea76e797c081b2/img71.jpg)
Содержание слайда: class Program
{
static void Main(string[] args)
{
Water water = new Water(WaterState.LIQUID);
water.Heat();
water.Frost();
water.Frost();
Console.Read();
}
}
enum WaterState
{
SOLID,
LIQUID,
GAS
}
class Water
{
public WaterState State { get; set; }
public Water(WaterState ws)
{
State = ws;
}
public void Heat()
{
if(State==WaterState.SOLID)
{
Console.WriteLine("Превращаем лед в жидкость");
State = WaterState.LIQUID;
}
else if (State == WaterState.LIQUID)
{
Console.WriteLine("Превращаем жидкость в пар");
State = WaterState.GAS;
}
else if (State == WaterState.GAS)
{
Console.WriteLine("Повышаем температуру водяного пара");
}
}
public void Frost()
{
if (State == WaterState.LIQUID)
{
Console.WriteLine("Превращаем жидкость в лед");
State = WaterState.SOLID;
}
else if (State == WaterState.GAS)
{
Console.WriteLine("Превращаем водяной пар в жидкость");
State = WaterState.LIQUID;
}
}
}
№73 слайд
![Вода имеет три состояния, и в](/documents_6/7b27c719721e5e21cdea76e797c081b2/img72.jpg)
Содержание слайда: Вода имеет три состояния, и в каждом методе нам надо смотреть на текущее состояние, чтобы произвести действия. В итоге с трех состояний уже получается нагромождение условных конструкций. Да и самим методов в классе Вода может также быть множество, где также надо будет действовать в зависимости от состояния. Поэтому, чтобы сделать программу более гибкой, в данном случае мы можем применить паттерн Состояние:
№74 слайд
![class Program class Program](/documents_6/7b27c719721e5e21cdea76e797c081b2/img73.jpg)
Содержание слайда: class Program
class Program
{
static void Main(string[] args)
{
Water water = new Water(new LiquidWaterState());
water.Heat();
water.Frost();
water.Frost();
Console.Read();
}
}
class Water
{
public IWaterState State { get; set; }
public Water(IWaterState ws)
{
State = ws;
}
public void Heat()
{
State.Heat(this);
}
public void Frost()
{
State.Frost(this);
}
}
interface IWaterState
{
void Heat(Water water);
void Frost(Water water);
}
class SolidWaterState : IWaterState
{
public void Heat(Water water)
{
Console.WriteLine("Превращаем лед в жидкость");
water.State = new LiquidWaterState();
}
public void Frost(Water water)
{
Console.WriteLine("Продолжаем заморозку льда");
}
}
class LiquidWaterState : IWaterState
{
public void Heat(Water water)
{
Console.WriteLine("Превращаем жидкость в пар");
water.State = new GasWaterState();
}
public void Frost(Water water)
{
Console.WriteLine("Превращаем жидкость в лед");
water.State = new SolidWaterState();
}
}
class GasWaterState : IWaterState
{
public void Heat(Water water)
{
Console.WriteLine("Повышаем температуру водяного пара");
}
public void Frost(Water water)
{
Console.WriteLine("Превращаем водяной пар в жидкость");
water.State = new LiquidWaterState();
}
}
№75 слайд
![Таким образом, реализация](/documents_6/7b27c719721e5e21cdea76e797c081b2/img74.jpg)
Содержание слайда: Таким образом, реализация паттерна Состояние позволяет вынести поведение, зависящее от текущего состояния объекта, в отдельные классы, и избежать перегруженности методов объекта условными конструкциями, как if..else или switch.
Кроме того, при необходимости мы можем ввести в систему новые классы состояний, а имеющиеся классы состояний использовать в других объектах.
Скачать все slide презентации Iterator Mediator Momento Observer State. Назначение паттерна Iterator одним архивом:
Похожие презентации
-
OOP with C. Introduction C. Data Types. Variables, expressions, statements. C decision and iteration constructs
-
Назначение и возможности языка PHP. Переменные, константы и типы данных РНР. Лекция 1
-
Основное назначение библиoтeки jQuery
-
Поведенческие паттерны
-
Типовые решения проектирования. Порождающие паттерны
-
Назначение PowerShell
-
Введение в паттерны
-
Finite state machines and VHDL
-
Паттерны поведения
-
Структурные паттерны