SlideShare a Scribd company logo
1 of 31
Польгун М.

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

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

2


Контекст – ситуация, в которой применяется
паттерн, достаточно типичная и распространенная.

(Имеется коллекция объектов)


Проблема – цель, которой хотят добиться в
контексте, в совокупности со всеми
ограничениями, присущими контексту. (Требуется

переработать объекты без раскрытия внутренней
реализации коллекции)


Решение – обобщенная архитектура, которая
достигает заданной цели при соблюдении набора
ограничений. (Перебор инкапсулируются в

отдельном классе)

3
 Наименование

 Задача

 Результат

/ последствия

4









Паттерны проектирования
Архитектурные паттерны
Аналитические паттерны
Паттерны рефакторинга (рефакторинги)
Паттерны тестирования приложений
Паттерны интеграции приложений
и.т.д.

5
Категория

Паттерны

Порождающие

Абстрактная фабрика, Одиночка, Прототип,
Строитель, Фабричный метод

Структурные

Адаптер, Декоратор, Заместитель, Компоновщик,
Мост, Приспособленец, Фасад

Поведения

Интерпретатор, Итератор, Команда, Наблюдатель,
Посетитель, Посредник, Состояние, Стратегия,
Хранитель, Цепочка обязанностей, Шаблонный
метод

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

7
8
public interface ILoger {
void LogError(string message);
void LogInfo(string message);
void LogException(Exception
exception);
}

public class DiagnosticScheduller {
private ILoger m_loger;
public DiagnosticScheduller (Configurator c,
Iloger loger) {
m_loger = loger ?? new NullableLoger();
}

}

private void LogMessage(string m) {
m_loger.LogInfo(m);
}

public class NullableLoger : ILoger
{
public void LogError(string message) {}
public void LogInfo(string message){}
public void LogException(Exception
exception){}
}

9
public class Loger : ILoger {
private readonly ILog m_log;
public Loger(ILog log) { m_log = log; }
public void LogError(string message){ m_log.Error(message);}
public void LogWarning(string message){ m_log.Warn(message);

}

public void LogException(Exception exception){
LogException(exception, "Exception caught");
}
private void LogException(Exception ex, string prefix){
LogError(string.Format("{0}: {1} - {2}", prefix, ex.GetType().Name, ex.Message));

}

}

if (ex.InnerException != null)
LogException(ex.InnerException, "Inner exception");

10
internal class WindowLog : ILoger {
private readonly frmMain m_form;
public WindowLog(frmMain logForm) {
m_form = logForm;
}
public void LogError(string message) {
StringBuilder sb = new StringBuilder("ERROR ");
sb.Append(DateTime.Now + ": " + message);
m_form.AppendText(sb.ToString());
}
public void LogWarning(string message) {
StringBuilder sb = new StringBuilder("WARNING ");
sb.Append(DateTime.Now + ": " + message);
m_form.AppendText(sb.ToString());
}
public void LogException(Exception exception) {
LogException(exception, "Exception caught");
}
private void LogException(Exception ex, string prefix){ ...}

}

11
Назначение: позволяет объекту варьировать
свое поведение в зависимости от
внутреннего состояния. Извне создается
впечатление, что изменился класс объекта.

12
public enum PaintMode {
None,
Point,
Line,
Polygon,
CompositePoint,
DragMarker,
}

class PrimitiveLayer…
public void MouseDownHandle(Point location, MouseButtons mouseButton)
{
if (m_paintMode != PaintMode.None) return;
var screenLocation = new GisPoint(location);
foreach (var primitive in m_primitiveLayer.Views.Reverse())
{...}
}
public void MouseMoveHandle(Point location, MouseButtons mouseButton)
{
switch (m_paintMode) {
case PaintMode.Line:
case PaintMode.CompositePoint:... break
case PaintMode.Polygon:... break;
case PaintMode.None:... break;

Самый первый вариант
}

}

case PaintMode.DragMarker: ... break;

public void MouseUpHandle(Point location, MouseButtons mouseButton)
{
if (m_paintMode == PaintMode.None ||
m_paintMode == PaintMode.DragMarker) {
...
if (m_paintMode == PaintMode.DragMarker)
m_paintMode = PaintMode.None;
}
else{...}
}
13
14
public class StateContext {
PaintState m_state;
public StateContext(PrimitiveLayer layer, Map map) {
Layer = layer;
m_state = NoneState.Instance;
m_drawer = new DoubleBufferDrawer(map);
}
public void SetState(PaintState state) {
m_state = state;
}
public PrimitiveLayer Layer { get; private set; }
public ExtendedPrimitive DragingObject { get; set; }
public void MouseDown(Point screenLocation, MouseButtons mouseButton) {
m_state.MouseDown(this, screenLocation, mouseButton);
}
public void MouseMove(Point screenLocation, MouseButtons mouseButton) {
m_state.MouseMove(this, screenLocation, mouseButton);
}

public void MouseUp(Point screenLocation, MouseButtons mouseButton) {
m_state.MouseUp(this, screenLocation, mouseButton);
}
public bool Drawing {

get { return m_state != NoneState.Instance; } }

}

15
public abstract class PaintState {
public abstract void MouseDown(StateContext context, Point screenLocation, MouseButtons mouseButton);
public abstract void MouseMove(StateContext context, Point screenLocation, MouseButtons mouseButton);
public abstract void MouseUp(StateContext context, Point screenLocation, MouseButtons mouseButton);
}

public class NoneState : PaintState {
public override void MouseDown(StateContext context, Point screenLocation, MouseButtons mouseButton)
{
foreach (var primitive in context.Layer.Primitives) {...}
}
public override void MouseMove(StateContext context, Point screenLocation, MouseButtons mouseButton)
{
...
}
public override void MouseUp(StateContext context, Point screenLocation, MouseButtons mouseButton)
{
...

}
}

16
class PrimitiveLayer…
StateContext m_context;
public PrimitiveLayer() {
m_context = new StateContext(this, map);
}
public void MouseDownHandle(Point location, MouseButtons mouseButton) {
DragMouseDx.Instance.Reset(location);
m_context.MouseDown(location, mouseButton);
m_map.Repaint();
}
public void MouseMoveHandle(Point location, MouseButtons mouseButton) {
if(ActivePrimitive == null ||
m_map.WorkMode != MapWorkMode.SelectObjects ||
DragMouseDx.Instance.PrEnable) return;

}

m_context.MouseMove(location, mouseButton);

public void MouseUpHandle(Point location, MouseButtons mouseButton) {
m_map.AllowScaling = true;
m_context.MouseUp(location, mouseButton);
}

17
Назначение: Гарантирует, что у класса есть только
один экземпляр, и предоставляет к нему глобальную
точку доступа.
Плюсы
 Контролируемый доступ к единственному
экземпляру;
 Имеется возможность обращаться через интерфейс
Минусы
 Глобальный объекты зачастую вредны, могут
привести к не масштабируемому проекту
 Усложняют написание модульных тестов

18
public sealed class LogHelper {
private sealed class LogHelperSingleton
{
private static readonly LogHelper instance = new LogHelper();
public static LogHelper Instance {
get { return instance; }
}
}
public static LogHelper Instance { get { return LogHelperSingleton.Instance; }}
private LogHelper() { ... }
public void AddError(string title, Exception exception) { ...}
public void AddMessage(string title, string message) { ... }
}
Обращение
LogHelper.Instance.AddError(“Ошибка сохранения”, excception);

19
Назначение: Динамически добавляет объекту
новые обязанности. Является гибкой
альтернативой порождения подклассов с
целью расширения функциональности.

20
21
В многих фреймворках современных платформ
программирования (.Net, Java SE) паттерн
декоратор используется для организации работы
с потоками ввода/вывода.

22
Stream file = new FileStream("log.dat", FileMode.Create);

Stream gzip = new GZipStream(file, CompressionLevel.Optimal);
Stream crypto = new
CryptoStream(gzip, encryptor, CryptoStreamMode.Write);
crypto.Write(data, 0, data.Length);

23
Назначение: определяет основу алгоритма и
позволяет подклассам переопределить
некоторые шаги алгоритма, не изменяя его
структуру в целом

24
25
Назначение: компонует объекты в
древовидные структуры для представления
иерархий часть-целое. Позволяет клиентам
единообразно трактовать индивидуальные и
составные объекты.

26
27
public abstract class MapVisible
{
public abstract void Draw(Graphics g);
public virtual bool CanCompose { get { return false; } }
public virtual void Add(MapVisible v)
{
throw new NotSupportedException("Не поддерживается");
}

public virtual void Remove(MapVisible v)
{
throw new NotSupportedException("Не поддерживается");
}

}

public virtual IEnumerable<MapVisible> Children
{
get { return Enumerable.Empty<MapVisible>(); }
}

28
public class PointView : MapVisible
{
public override void Draw(Graphics g)
{
g.FillEllipse(s_brush, rect);
g.DrawEllipse(s_pen, rect);
}
}

29
public class LineView : MapVisible
{
protected List<MapVisible> m_points = new List<MapVisible>();
public override void Draw (Graphics g) {
PointF[] cpPoints = Получить набор точек из m_points;
g.DrawLines(s_linePen, cpPoints);

}

foreach (MapVisible pnt in m_points)
pnt.Draw(g);

public override bool CanCompose { get {return true; } }
public override void Add(MapVisible v) { m_points.Add(v); }
public override void Remove(MapVisible v) { m_points.Remove(v); }

}

public override IEnumerable<MapVisible> Children
{
get { return m_points; }
}

30










Гамма Э. и др. Приемы объектноориентированного проектирования. Паттерны
проектирования. - СПб.: Питер, 2007. – 366 с., ил.
Фримен Э. и др. Паттерны проектирования. – СПб.:
Питер, 2011. – 656 с., ил.

Ларман К. Применение UML 2.0 и шаблонов
проектирования. Практическое руководство. 3-е издание.
– Пер. с англ. – М.: ООО «И.Д. Вильямс», 2013. – 736 с.: ил.
Мартин Р. Мартин М. Принципы, паттерны и методики
гибкой разработки на языке C#. – СПб.: СимволПлюс, 2011. – 768 с., ил.
Фаулер М. Рефакторинг. Улучшение существующего кода. –
СПб.: Символ-Плюс, 2008. – 432 с., ил.
http://goo.gl/raOSl

31

More Related Content

Viewers also liked

Разработка веб-сервисов осень 2013 лекция 7
Разработка веб-сервисов осень 2013 лекция 7Разработка веб-сервисов осень 2013 лекция 7
Разработка веб-сервисов осень 2013 лекция 7Technopark
 
шаблоны проектирования
шаблоны проектированияшаблоны проектирования
шаблоны проектированияksmster
 
C++ осень 2012 лекция 7
C++ осень 2012 лекция 7C++ осень 2012 лекция 7
C++ осень 2012 лекция 7Technopark
 
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFШаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFSergey Nemchinsky
 
Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARNTechnopark
 
Лекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuЛекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuTechnopark
 
Лекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelЛекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelTechnopark
 

Viewers also liked (7)

Разработка веб-сервисов осень 2013 лекция 7
Разработка веб-сервисов осень 2013 лекция 7Разработка веб-сервисов осень 2013 лекция 7
Разработка веб-сервисов осень 2013 лекция 7
 
шаблоны проектирования
шаблоны проектированияшаблоны проектирования
шаблоны проектирования
 
C++ осень 2012 лекция 7
C++ осень 2012 лекция 7C++ осень 2012 лекция 7
C++ осень 2012 лекция 7
 
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFШаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
 
Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARN
 
Лекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuЛекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.Ru
 
Лекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelЛекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель Pregel
 

Similar to Паттерны проектирования

Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
 
"Погружение в Robolectric" Дмитрий Костырев (Avito)
"Погружение в Robolectric"  Дмитрий Костырев (Avito)"Погружение в Robolectric"  Дмитрий Костырев (Avito)
"Погружение в Robolectric" Дмитрий Костырев (Avito)AvitoTech
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Googleyaevents
 
Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур
 Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур  Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур
Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур it-people
 
MVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяMVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяYuri Shmakov
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Sigma Software
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.Doomer Samoiloff
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?Tatyanazaxarova
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Разбираемся с CoordinatorLayout
Разбираемся с CoordinatorLayoutРазбираемся с CoordinatorLayout
Разбираемся с CoordinatorLayoutRambler Android
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
Techtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real lifeTechtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real lifeDA-14
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
Lec 2 Java
Lec 2 JavaLec 2 Java
Lec 2 Javaitc73
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Dima Dzuba
 
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Mikhail Kurnosov
 

Similar to Паттерны проектирования (20)

Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
 
"Погружение в Robolectric" Дмитрий Костырев (Avito)
"Погружение в Robolectric"  Дмитрий Костырев (Avito)"Погружение в Robolectric"  Дмитрий Костырев (Avito)
"Погружение в Robolectric" Дмитрий Костырев (Avito)
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур
 Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур  Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур
Xamarin: кроссплатформенные грабли, Дмитрий Моисеев, СКБ Контур
 
MVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяMVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоваться
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Разбираемся с CoordinatorLayout
Разбираемся с CoordinatorLayoutРазбираемся с CoordinatorLayout
Разбираемся с CoordinatorLayout
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Techtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real lifeTechtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real life
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Lec 2 Java
Lec 2 JavaLec 2 Java
Lec 2 Java
 
Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9Проектирование программных систем. Занятие 9
Проектирование программных систем. Занятие 9
 
Lec 2
Lec 2Lec 2
Lec 2
 
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
Лекция 12 (часть 2): Языки программирования семейства PGAS: IBM X10
 

Паттерны проектирования

  • 2. Паттерн – повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках часто возникающего контекста. Это не законченный образец, который может быть прямо преобразован в код: это всего лишь пример решения задачи, который можно использовать в различных ситуациях. 2
  • 3.  Контекст – ситуация, в которой применяется паттерн, достаточно типичная и распространенная. (Имеется коллекция объектов)  Проблема – цель, которой хотят добиться в контексте, в совокупности со всеми ограничениями, присущими контексту. (Требуется переработать объекты без раскрытия внутренней реализации коллекции)  Решение – обобщенная архитектура, которая достигает заданной цели при соблюдении набора ограничений. (Перебор инкапсулируются в отдельном классе) 3
  • 4.  Наименование  Задача  Результат / последствия 4
  • 5.        Паттерны проектирования Архитектурные паттерны Аналитические паттерны Паттерны рефакторинга (рефакторинги) Паттерны тестирования приложений Паттерны интеграции приложений и.т.д. 5
  • 6. Категория Паттерны Порождающие Абстрактная фабрика, Одиночка, Прототип, Строитель, Фабричный метод Структурные Адаптер, Декоратор, Заместитель, Компоновщик, Мост, Приспособленец, Фасад Поведения Интерпретатор, Итератор, Команда, Наблюдатель, Посетитель, Посредник, Состояние, Стратегия, Хранитель, Цепочка обязанностей, Шаблонный метод 6
  • 7. Назначение: определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Позволяет изменить алгоритмы независимо от клиентов. 7
  • 8. 8
  • 9. public interface ILoger { void LogError(string message); void LogInfo(string message); void LogException(Exception exception); } public class DiagnosticScheduller { private ILoger m_loger; public DiagnosticScheduller (Configurator c, Iloger loger) { m_loger = loger ?? new NullableLoger(); } } private void LogMessage(string m) { m_loger.LogInfo(m); } public class NullableLoger : ILoger { public void LogError(string message) {} public void LogInfo(string message){} public void LogException(Exception exception){} } 9
  • 10. public class Loger : ILoger { private readonly ILog m_log; public Loger(ILog log) { m_log = log; } public void LogError(string message){ m_log.Error(message);} public void LogWarning(string message){ m_log.Warn(message); } public void LogException(Exception exception){ LogException(exception, "Exception caught"); } private void LogException(Exception ex, string prefix){ LogError(string.Format("{0}: {1} - {2}", prefix, ex.GetType().Name, ex.Message)); } } if (ex.InnerException != null) LogException(ex.InnerException, "Inner exception"); 10
  • 11. internal class WindowLog : ILoger { private readonly frmMain m_form; public WindowLog(frmMain logForm) { m_form = logForm; } public void LogError(string message) { StringBuilder sb = new StringBuilder("ERROR "); sb.Append(DateTime.Now + ": " + message); m_form.AppendText(sb.ToString()); } public void LogWarning(string message) { StringBuilder sb = new StringBuilder("WARNING "); sb.Append(DateTime.Now + ": " + message); m_form.AppendText(sb.ToString()); } public void LogException(Exception exception) { LogException(exception, "Exception caught"); } private void LogException(Exception ex, string prefix){ ...} } 11
  • 12. Назначение: позволяет объекту варьировать свое поведение в зависимости от внутреннего состояния. Извне создается впечатление, что изменился класс объекта. 12
  • 13. public enum PaintMode { None, Point, Line, Polygon, CompositePoint, DragMarker, } class PrimitiveLayer… public void MouseDownHandle(Point location, MouseButtons mouseButton) { if (m_paintMode != PaintMode.None) return; var screenLocation = new GisPoint(location); foreach (var primitive in m_primitiveLayer.Views.Reverse()) {...} } public void MouseMoveHandle(Point location, MouseButtons mouseButton) { switch (m_paintMode) { case PaintMode.Line: case PaintMode.CompositePoint:... break case PaintMode.Polygon:... break; case PaintMode.None:... break; Самый первый вариант } } case PaintMode.DragMarker: ... break; public void MouseUpHandle(Point location, MouseButtons mouseButton) { if (m_paintMode == PaintMode.None || m_paintMode == PaintMode.DragMarker) { ... if (m_paintMode == PaintMode.DragMarker) m_paintMode = PaintMode.None; } else{...} } 13
  • 14. 14
  • 15. public class StateContext { PaintState m_state; public StateContext(PrimitiveLayer layer, Map map) { Layer = layer; m_state = NoneState.Instance; m_drawer = new DoubleBufferDrawer(map); } public void SetState(PaintState state) { m_state = state; } public PrimitiveLayer Layer { get; private set; } public ExtendedPrimitive DragingObject { get; set; } public void MouseDown(Point screenLocation, MouseButtons mouseButton) { m_state.MouseDown(this, screenLocation, mouseButton); } public void MouseMove(Point screenLocation, MouseButtons mouseButton) { m_state.MouseMove(this, screenLocation, mouseButton); } public void MouseUp(Point screenLocation, MouseButtons mouseButton) { m_state.MouseUp(this, screenLocation, mouseButton); } public bool Drawing { get { return m_state != NoneState.Instance; } } } 15
  • 16. public abstract class PaintState { public abstract void MouseDown(StateContext context, Point screenLocation, MouseButtons mouseButton); public abstract void MouseMove(StateContext context, Point screenLocation, MouseButtons mouseButton); public abstract void MouseUp(StateContext context, Point screenLocation, MouseButtons mouseButton); } public class NoneState : PaintState { public override void MouseDown(StateContext context, Point screenLocation, MouseButtons mouseButton) { foreach (var primitive in context.Layer.Primitives) {...} } public override void MouseMove(StateContext context, Point screenLocation, MouseButtons mouseButton) { ... } public override void MouseUp(StateContext context, Point screenLocation, MouseButtons mouseButton) { ... } } 16
  • 17. class PrimitiveLayer… StateContext m_context; public PrimitiveLayer() { m_context = new StateContext(this, map); } public void MouseDownHandle(Point location, MouseButtons mouseButton) { DragMouseDx.Instance.Reset(location); m_context.MouseDown(location, mouseButton); m_map.Repaint(); } public void MouseMoveHandle(Point location, MouseButtons mouseButton) { if(ActivePrimitive == null || m_map.WorkMode != MapWorkMode.SelectObjects || DragMouseDx.Instance.PrEnable) return; } m_context.MouseMove(location, mouseButton); public void MouseUpHandle(Point location, MouseButtons mouseButton) { m_map.AllowScaling = true; m_context.MouseUp(location, mouseButton); } 17
  • 18. Назначение: Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа. Плюсы  Контролируемый доступ к единственному экземпляру;  Имеется возможность обращаться через интерфейс Минусы  Глобальный объекты зачастую вредны, могут привести к не масштабируемому проекту  Усложняют написание модульных тестов 18
  • 19. public sealed class LogHelper { private sealed class LogHelperSingleton { private static readonly LogHelper instance = new LogHelper(); public static LogHelper Instance { get { return instance; } } } public static LogHelper Instance { get { return LogHelperSingleton.Instance; }} private LogHelper() { ... } public void AddError(string title, Exception exception) { ...} public void AddMessage(string title, string message) { ... } } Обращение LogHelper.Instance.AddError(“Ошибка сохранения”, excception); 19
  • 20. Назначение: Динамически добавляет объекту новые обязанности. Является гибкой альтернативой порождения подклассов с целью расширения функциональности. 20
  • 21. 21
  • 22. В многих фреймворках современных платформ программирования (.Net, Java SE) паттерн декоратор используется для организации работы с потоками ввода/вывода. 22
  • 23. Stream file = new FileStream("log.dat", FileMode.Create); Stream gzip = new GZipStream(file, CompressionLevel.Optimal); Stream crypto = new CryptoStream(gzip, encryptor, CryptoStreamMode.Write); crypto.Write(data, 0, data.Length); 23
  • 24. Назначение: определяет основу алгоритма и позволяет подклассам переопределить некоторые шаги алгоритма, не изменяя его структуру в целом 24
  • 25. 25
  • 26. Назначение: компонует объекты в древовидные структуры для представления иерархий часть-целое. Позволяет клиентам единообразно трактовать индивидуальные и составные объекты. 26
  • 27. 27
  • 28. public abstract class MapVisible { public abstract void Draw(Graphics g); public virtual bool CanCompose { get { return false; } } public virtual void Add(MapVisible v) { throw new NotSupportedException("Не поддерживается"); } public virtual void Remove(MapVisible v) { throw new NotSupportedException("Не поддерживается"); } } public virtual IEnumerable<MapVisible> Children { get { return Enumerable.Empty<MapVisible>(); } } 28
  • 29. public class PointView : MapVisible { public override void Draw(Graphics g) { g.FillEllipse(s_brush, rect); g.DrawEllipse(s_pen, rect); } } 29
  • 30. public class LineView : MapVisible { protected List<MapVisible> m_points = new List<MapVisible>(); public override void Draw (Graphics g) { PointF[] cpPoints = Получить набор точек из m_points; g.DrawLines(s_linePen, cpPoints); } foreach (MapVisible pnt in m_points) pnt.Draw(g); public override bool CanCompose { get {return true; } } public override void Add(MapVisible v) { m_points.Add(v); } public override void Remove(MapVisible v) { m_points.Remove(v); } } public override IEnumerable<MapVisible> Children { get { return m_points; } } 30
  • 31.       Гамма Э. и др. Приемы объектноориентированного проектирования. Паттерны проектирования. - СПб.: Питер, 2007. – 366 с., ил. Фримен Э. и др. Паттерны проектирования. – СПб.: Питер, 2011. – 656 с., ил. Ларман К. Применение UML 2.0 и шаблонов проектирования. Практическое руководство. 3-е издание. – Пер. с англ. – М.: ООО «И.Д. Вильямс», 2013. – 736 с.: ил. Мартин Р. Мартин М. Принципы, паттерны и методики гибкой разработки на языке C#. – СПб.: СимволПлюс, 2011. – 768 с., ил. Фаулер М. Рефакторинг. Улучшение существующего кода. – СПб.: Символ-Плюс, 2008. – 432 с., ил. http://goo.gl/raOSl 31