2. Паттерн – повторяемая архитектурная
конструкция, представляющая собой
решение проблемы проектирования в рамках
часто возникающего контекста.
Это не законченный образец, который может
быть прямо преобразован в код: это всего
лишь пример решения задачи, который
можно использовать в различных ситуациях.
2
3.
Контекст – ситуация, в которой применяется
паттерн, достаточно типичная и распространенная.
(Имеется коллекция объектов)
Проблема – цель, которой хотят добиться в
контексте, в совокупности со всеми
ограничениями, присущими контексту. (Требуется
переработать объекты без раскрытия внутренней
реализации коллекции)
Решение – обобщенная архитектура, которая
достигает заданной цели при соблюдении набора
ограничений. (Перебор инкапсулируются в
отдельном классе)
3
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
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
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
26. Назначение: компонует объекты в
древовидные структуры для представления
иерархий часть-целое. Позволяет клиентам
единообразно трактовать индивидуальные и
составные объекты.
26
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