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

31
Паттерны проектирования Польгун М. 1

description

 

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

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

1

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

Польгун М.

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

2

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

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

Что такое паттерн?

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

3

Контекст – ситуация, в которой применяется паттерн, достаточно типичная и распространенная. (Имеется коллекция объектов)

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

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

Контекст, проблема, решение

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

4

НаименованиеЗадачаРезультат / последствия

Из чего состоит паттерн?

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

5

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

Какие паттерны бывают?

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

6

Категория Паттерны

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

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

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

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

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

7

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

Стратегия (Strategy)

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

8

Пример (диагностическая платформа)

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

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){}}

Пример (диагностическая платформа)

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

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");

}}

Пример (диагностическая платформа)

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

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){ ...}}

Пример (диагностическая платформа)

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

12

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

Состояние (State)

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

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{...}}

Пример (редактор маршрутов) – до…

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

14

Пример (редактор маршрутов) – после…

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

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; } }}

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

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)

{

...

}

}

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

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);}

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

18

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

Плюсы Контролируемый доступ к единственному

экземпляру; Имеется возможность обращаться через интерфейс

Минусы Глобальный объекты зачастую вредны, могут

привести к не масштабируемому проекту Усложняют написание модульных тестов

Одиночка (Singleton)

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

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);

Пример (почти все программы…)

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

20

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

Декоратор (Decorator)

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

21

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

22

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

Пример (.Net Framework)

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

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);

Пример (.Net Framework)

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

24

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

Шаблонный метод (Template Method)

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

25

Пример (редактор маршрутов)

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

26

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

Компоновщик (Composite)

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

27

Пример (API отображения объектов на карте)

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

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>(); } }}

Пример (API отображения объектов на карте)

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

29

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

g.DrawEllipse(s_pen, rect); }}

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

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; } }}

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

31

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

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

Ларман К. Применение UML 2.0 и шаблонов проектирования. Практическое руководство. 3-е издание. – Пер. с англ. – М.: ООО «И.Д. Вильямс», 2013. – 736 с.: ил.

Мартин Р. Мартин М. Принципы, паттерны и методики гибкой разработки на языке C#. – СПб.: Символ-Плюс, 2011. – 768 с., ил.

Фаулер М. Рефакторинг. Улучшение существующего кода. – СПб.: Символ-Плюс, 2008. – 432 с., ил.

http://goo.gl/raOSl

Информационные источники