SlideShare une entreprise Scribd logo
1  sur  52
Лучшие практики разработки ПО Принципы гибкого проектирования Юрий Трухин senior developer, CNIPGIS LLC Microsoft Student Partner Guru
беларуская версія Лепшыя практыкі распрацоўкі праграмнага забеспячэння прынцыпы гнуткага праектавання Юрий Трухин senior developer, CNIPGIS LLC Microsoft Student Partner Guru
Признаки плохого дизайна ПО
Признаки плохого дизайна ПО Жесткость: дизайн трудно поддается изменению Хрупкость: дизайн легко разрушается Косность: дизайн трудно использовать повторно Вязкость: трудно добиться желаемого Ненужная сложность: избыточное проектирование Ненужные повторения: чрезмерное использование копирования и вставки Непрозрачность: плохо выраженная цель Часто эти признаки появляются в результате нарушения одного из принципов проектирования.
Пример загнивания программы
public partial class Copier     { public static void Copy()         {             int c;             while ((c = Keyboard.Read()) != -1)             {                 Printer.Write(c);             }         } }
public class CopierWithPerfocards     {         /// <summary>         /// не забудьте сбросить этот флаг         /// </summary>         private static boolptFlag = false; public static void Copy()         {             int c;             while ((c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != -1) Printer.Write(c);         }      }
public class CopierWithPerfocardsReadAndWrite     {         //не забудьте сбросить этот флаг public static boolptFlag = false;         public static boolpunchFlag = false;         public static void Copy()         {             int c;             while ((c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != -1) punchFlag ? PaperTape.punchFlag(c) : Printer.Write(c);         }      }
public interface Reader      {          int Read();      }      public class KeyboardReader : Reader      {          public int Read() { return Keyboard.Read(); };      }      public partial class Copier      {          public static Reader reader = new KeyboardReader();          public static void Copy()          { var c;              while ((c = (reader.Read())) != -1 )              {                  Printer.Write(c);              }          }      }
Принципы гибкого проектирования
Принципы гибкого проектирования Принцип единственной обязанности Принцип открытости/закрытости Принцип подстановки Лисков Принцип инверсии зависимости Принцип разделения интерфейсов Принцип эквивалентности повторного использования и выпуска Принцип общей закрытости Принцип совместного повторного использования Принцип ацикличности зависимостей Принцип устойчивых зависимостей Принцип устойчивых абстракций
Принцип единственной обязанности (SRP) «Никто кроме Будды не должен брать на себя ответственность за сокровенные знания»  Э.Кобхэм Брюэр, 1897
Принцип единственной обязанности (SRP) У класса должна быть только одна причина для изменения. Любое изменение требований проявляется в изменении распределения обязанностей между классами. Если класс берет на себя несколько обязанностей – у него появляется несколько причин для изменения. Если класс отвечает за несколько действий, его обязанности оказываются связанными.  Это является причиной хрупкого дизайна приложений.
Принцип единственной обязанности (SRP) Более одной обязанности Rectangle Приложение «Вычислительная геометрия» +draw() +area() : double Графическое приложение GUI
Принцип единственной обязанности (SRP) Проблемы:
Принцип единственной обязанности (SRP) Проблемы: В приложение «Вычислительная геометрия» попадает не нужная логика вместе с классом Rectangle. Если изменение графического приложения потребует изменить класс Rectangle, придется заново собирать, тестировать и развертывать приложение «Вычислительная геометрия». … или приложение «Вычислительная геометрия» неожиданно может перестать работать
Принцип единственной обязанности (SRP) Обязанности разделены Rectangle GeometricRectangle Приложение «Вычислительная геометрия» Графическое приложение +draw() +area() : double GUI
Принцип единственной обязанности (SRP) Обязанность – причина изменения Если вы можете найти несколько причин для изменения – у класса несколько обязанностей.
Принцип единственной обязанности (SRP) Пример: Public interface Modem { 	public void Dial(string pno); 	public void Hangup(); 	public void Send (char c); 	public char Recv();  } Сколько обязанностей у интерфейса Modem?
Принцип единственной обязанности (SRP) Сколько обязанностей?: Public interface Modem { 	public void Dial(string pno); //управление соединением 	public void Hangup();//управление соединением 	public void Send (char c);//передача данных 	public char Recv(); //передача данных } Нужно ли разделить интерфейс?
Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: ДА! Если может потребоваться изменение сигнатуры методов управления соединением, класс, вызывающий send и receive придется повторно компилировать и развертывать чаще, чем хотелось бы. Это приводит к жесткости дизайна. Следует разделить интерфейс на DataChannelи Connection
Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: НЕТ! Если приложение не модифицируют таким образом, что обязанности изменяются порознь, то разделять нет необходимости. Это приводит к излишней сложности. Изменения интерфейса не требуются.
Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: НЕТ! Если приложение не модифицируют таким образом, что обязанности изменяются порознь, то разделять нет необходимости. Это приводит к излишней сложности. Изменения интерфейса не требуются. Вывод: ось изменения становится таковой, если изменение имеет место. Если на то нет причин, неразумно применять ЛЮБОЙ принцип проектирования.
Принцип единственной обязанности (SRP) Разделение связанных обязанностей. Обеспечение сохранности. Employee +CalculatePay +Store Persistense System Связь бизнес-правил и подсистемы сохраниния -> неприятности! Обычно тесты заставляют их разделять, если нет – в случае если появляется жесткость и хрупкость – нужен рефакторинг! (Для данного случая применимы паттерны Фасад, Объект доступа к данным, Прокси для разделения обязанностей).
Принцип открытости-закрытости «Голланская дверь: существительное. Дверь, разделенная на две части по горизонтали так, что каждая створка может открываться и закрываться независимо»  The American Heritage Dictionary of English language, 2000
Принцип открытости-закрытости Программные сущности (классы, модули, функции) должны быть открыты для расширения и закрыты для модификации. Если единственное изменение в каком-то месте программы приводит к каскаду изменений в зависимых модулях – это признак жесткого дизайна.
Принцип открытости-закрытости Основные храктеристики модулей, разработанных в соответствии с принципом открытости-закрытости: Они открыты для расширения (поведение модуля можно расширить, можно менять состав функций модуля). Они закрыты для модификации (расширение поведение модуля не сопряжено с изменением в исходном или двоичном коде модуля). Как это сделать?
Принцип открытости-закрытости Как это сделать? С ПОМОЩЬЮ АБСТРАКЦИИ! Абстракция – абстрактный базовый класс, поведение – производный класс.  Модуль, манипулирующий абстракцией можно сделать закрытым для модификации – он зависит от ФИКСИРОВАННОЙ абстракции. Модуль при этом остается расширяемым.
Принцип открытости-закрытости Пример: Client Server Класс Client не является открытым и закрытым.
Принцип открытости-закрытости Применив паттерн «Стратегия» получим: “interface” Client Interface Client Server Класс Client одновременно является открытым и закрытым.
Принцип открытости-закрытости Альтернатива: Паттерн «Шаблонный метод» Открытые методы в policy реализуют некую политику, они аналогичны методам класса Client (описывают определенные функции в терминах абстрактных интерфейсов, часть класса policy, в C# это абстрактные методы, реализуются в подтипах policy). Поведения, описанные внутри policy, можно расширять и модифицировать. Policy Implementation +PolicyFunction() #ServiceFunction() #ServiceFunctiom
Принцип открытости-закрытости Пример принципа OCP
Принцип открытости-закрытости --shape.h-------------------------------------------------------------------- enumShareType (circle, square); struct Shape { ShapeTypeitsType; } --circle.h------------------------------------------------------------------- struct Circle { ShapeTypeitsType;     double itsRadius;     Point itsCenter; }; void DrawCircle(struct Circle*); --square.h------------------------------------------------------------------- struct Square { ShapeTypeitsType;     double itsSide;     Point itsTopLeft; }; void DrawSquare(struct Square*);
Принцип открытости-закрытости --drawAllShapes.cc----------------------------------------------------------- typedefstruct Shape *ShapePointer;     //функция не может быть закрытой для добавления других фигур, //не удовлетворяет принципам OCP void DrawAllShapes(ShapePointer list[], int n) {     int i;     for (i=0; i<n; i++)     { struct Shape* s = list[i];         switch (s->itsType)         {             case square: DrawSquare((struct Square*)s);                     break;             case circle: DrawCircle((struct Circle*)s);                         break;         }     } } ///Резюме: ///это решение жесткое, ///тк после добавление фигуры Triange(треугольник) ///необходимо заново откомпилировать и развернуть файлы , содержащие опредлеление ///Shape, Square,Circle и DrawAllShapes. /// ///это решение хрупкое, ///т.к. есть много других switch/case и if/else, которые сложно отыскать и понять. /// ///это решение костное, потому что всякий, кто попытается использовать  ///функцию DrawAllShapes в другой программе, вынужден будет тащить за собой  ///определения Square и Circle, даже если в этой программе они не используются.
Принцип открытости-закрытости public interface Shape     {         void Draw();     }     public class Square : Shape     {         public void Draw()         {             //нарисовать квадрат         }     } public class Circle : Shape     {         public void Draw()         {             //нарисовать круг         }     } public void DrawAllShape(IList shapes)     { foreach (Shape shape in shapes) shape.Draw();     }
Принцип открытости-закрытости Внимание, изменились требования!
Принцип открытости-закрытости Изменившиеся требования Необходимо, чтобы все круги рисовались раньше всех квадратов.
Принцип открытости-закрытости Вывод 1 Модель Shape не является естественной в системе, где упорядоченность связана с типом фигуры. Каким бы закрытым не был модуль, всегда найдется такое изменение, для которых он не закрыт. Не существует моделей, естественных во всех контекстах! Проектировщик должен решить, от каких изменений закрыть дизайн. OCP применим только с вероятными изменениями.
Принцип открытости-закрытости Расстановка «точек подключения» «Обманул меня раз». Первоначально код пишется без учета возможных изменений. Если изменение происходят – реализуется абстракция, в будущем защищающие от подобного рода изменений. «Стимулирование изменений»  Сначала пишем тесты. Разработку ведем очень короткими циклами, измеряемыми в днях, а не в неделях Разрабатываем содержательные функции до инфраструктуры и часто демонстрируем их заинтересованным сторонам Первую версию ПО выпускаем быстро, а последующие часто.
Принцип открытости-закрытости Заключение Следование этому принципу позволит получить от ООП максимум обещанного: гибкость, возможность повторного использования и удобство сопровождения. Отказ от преждевременного абстрагирования столь же важен, как и само абстрагирование.
Принцип подстановки лисков «Должна быть возможность вместо базового типа подставить любой его подтип»
Принцип инверсии зависимостей Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Принцип разделения интерфейсов Клиенты не должны вынужденно зависеть от методов, которыми не пользуются.
Принцип эквивалентности повторного использования и выпуска Единица повторного использования равна единице выпуска. (либо все классы, включенные в компонент можно повторно использовать, либо ни один!)
Принцип общей закрытости Все классы внутри компонента должны быть закрыты относительно изменений одного и того же вида. Изменение, затрагивающее компонент, должно затрагивать все классы в этом компоненте и только в нем.
Принцип совместного повторного использования Все классы внутри компонента используются совместно. Если вы можете повторно использовать один класс, то можете использовать и остальные.
Принцип ацикличности зависимостей В графе зависимостей между компонентами не должно быть циклов
Принцип устойчивых зависимостей Зависимости должны быть направлены в сторону устойчивости (изменяемые компоненты должны быть сверху графа, и из них собирается неизменяемый)
Принцип устойчивых абстракций Компонент должен быть столь же абстрактным, сколь и устойчивым (иначе устойчивость будет препятствовать его расширению).
Что дальше? ,[object Object]
Prism
Вред реинжиниринга

Contenu connexe

Tendances

C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5Technopark
 
PureMVC в картинках - часть 1
PureMVC в картинках - часть 1PureMVC в картинках - часть 1
PureMVC в картинках - часть 1Rostyslav Siryk
 
Cтиль программирования
Cтиль программированияCтиль программирования
Cтиль программированияConstantin Kichinsky
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноCUSTIS
 
C++ осень 2013 лекция 9
C++ осень 2013 лекция 9C++ осень 2013 лекция 9
C++ осень 2013 лекция 9Technopark
 
C++ осень 2013 лекция 2
C++ осень 2013 лекция 2C++ осень 2013 лекция 2
C++ осень 2013 лекция 2Technopark
 
AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)Andrey Gordienkov
 
Aspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design PatternsAspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design PatternsAndrey Gordienkov
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеSergey Nemchinsky
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4Technopark
 
C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.Igor Shkulipa
 
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документированиеСтажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование7bits
 
Шаблоны разработки ПО. Рефакторинг
Шаблоны разработки ПО. РефакторингШаблоны разработки ПО. Рефакторинг
Шаблоны разработки ПО. РефакторингSergey Nemchinsky
 
C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.Igor Shkulipa
 

Tendances (16)

C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5
 
PureMVC в картинках - часть 1
PureMVC в картинках - часть 1PureMVC в картинках - часть 1
PureMVC в картинках - часть 1
 
Cтиль программирования
Cтиль программированияCтиль программирования
Cтиль программирования
 
Секрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдноСекрет производства: программный продукт, за который не будет стыдно
Секрет производства: программный продукт, за который не будет стыдно
 
C++ осень 2013 лекция 9
C++ осень 2013 лекция 9C++ осень 2013 лекция 9
C++ осень 2013 лекция 9
 
C++ осень 2013 лекция 2
C++ осень 2013 лекция 2C++ осень 2013 лекция 2
C++ осень 2013 лекция 2
 
AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)
 
Aspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design PatternsAspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design Patterns
 
Refactoring
RefactoringRefactoring
Refactoring
 
лек13 4
лек13 4лек13 4
лек13 4
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. Введние
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4
 
C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.
 
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документированиеСтажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование
Стажировка-2015. Разработка. Занятие 8. Абстракции, именование,документирование
 
Шаблоны разработки ПО. Рефакторинг
Шаблоны разработки ПО. РефакторингШаблоны разработки ПО. Рефакторинг
Шаблоны разработки ПО. Рефакторинг
 
C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.C++ Базовый. Занятие 11.
C++ Базовый. Занятие 11.
 

En vedette

Yuri Trukhin - Microsoft4students
Yuri Trukhin - Microsoft4studentsYuri Trukhin - Microsoft4students
Yuri Trukhin - Microsoft4studentsbeloslab
 
Konstantin Slisenko - Belarus Open Source Lab
Konstantin Slisenko - Belarus Open Source LabKonstantin Slisenko - Belarus Open Source Lab
Konstantin Slisenko - Belarus Open Source Labbeloslab
 
Mr. Ankur Sharma - PDE good practices
Mr. Ankur Sharma - PDE good practicesMr. Ankur Sharma - PDE good practices
Mr. Ankur Sharma - PDE good practicesbeloslab
 
VoiceThread
VoiceThreadVoiceThread
VoiceThreadKpabs
 
Pavel Rumantsev - Java Script
Pavel Rumantsev - Java ScriptPavel Rumantsev - Java Script
Pavel Rumantsev - Java Scriptbeloslab
 
Pavel Rumantsev - Html5
Pavel Rumantsev - Html5Pavel Rumantsev - Html5
Pavel Rumantsev - Html5beloslab
 

En vedette (8)

Yuri Trukhin - Microsoft4students
Yuri Trukhin - Microsoft4studentsYuri Trukhin - Microsoft4students
Yuri Trukhin - Microsoft4students
 
Tarefa14
Tarefa14Tarefa14
Tarefa14
 
Konstantin Slisenko - Belarus Open Source Lab
Konstantin Slisenko - Belarus Open Source LabKonstantin Slisenko - Belarus Open Source Lab
Konstantin Slisenko - Belarus Open Source Lab
 
Mr. Ankur Sharma - PDE good practices
Mr. Ankur Sharma - PDE good practicesMr. Ankur Sharma - PDE good practices
Mr. Ankur Sharma - PDE good practices
 
Raissa
RaissaRaissa
Raissa
 
VoiceThread
VoiceThreadVoiceThread
VoiceThread
 
Pavel Rumantsev - Java Script
Pavel Rumantsev - Java ScriptPavel Rumantsev - Java Script
Pavel Rumantsev - Java Script
 
Pavel Rumantsev - Html5
Pavel Rumantsev - Html5Pavel Rumantsev - Html5
Pavel Rumantsev - Html5
 

Similaire à Yuri Trukhin - Software developement best practices

Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.Igor Shkulipa
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpgeekfamilyrussia
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpGoSharp
 
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПОЕвгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПОLuxoft Education Center
 
C++ Базовый. Занятие 15.
C++ Базовый. Занятие 15.C++ Базовый. Занятие 15.
C++ Базовый. Занятие 15.Igor Shkulipa
 
SOLID Principles in the real world
SOLID Principles in the real worldSOLID Principles in the real world
SOLID Principles in the real worldEPAM
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...Timur Shaporev
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.Igor Shkulipa
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Sergey Nemchinsky
 
Спецкурс 2014, занятие 3. Абстракции, именование, документирование
Спецкурс 2014, занятие 3. Абстракции, именование, документированиеСпецкурс 2014, занятие 3. Абстракции, именование, документирование
Спецкурс 2014, занятие 3. Абстракции, именование, документирование7bits
 
Gang of four review.Structural patterns
Gang of four review.Structural patternsGang of four review.Structural patterns
Gang of four review.Structural patternsMykyta Hopkalo
 
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar..."The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...DevClub_lv
 
C++ осень 2012 лекция 1
C++ осень 2012 лекция 1C++ осень 2012 лекция 1
C++ осень 2012 лекция 1Technopark
 
Чистая архитектура, Артур Бадретдинов АБЦТ
Чистая архитектура, Артур Бадретдинов АБЦТЧистая архитектура, Артур Бадретдинов АБЦТ
Чистая архитектура, Артур Бадретдинов АБЦТСбертех | SberTech
 

Similaire à Yuri Trukhin - Software developement best practices (20)

Tdd php
Tdd phpTdd php
Tdd php
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharp
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharp
 
Design Rules And Principles
Design Rules And PrinciplesDesign Rules And Principles
Design Rules And Principles
 
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПОЕвгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
 
C++ Базовый. Занятие 15.
C++ Базовый. Занятие 15.C++ Базовый. Занятие 15.
C++ Базовый. Занятие 15.
 
SOLID Principles in the real world
SOLID Principles in the real worldSOLID Principles in the real world
SOLID Principles in the real world
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...
Отображение языков высокого уровня на архитектуру ЭВМ на примере языка C и ос...
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"
 
Спецкурс 2014, занятие 3. Абстракции, именование, документирование
Спецкурс 2014, занятие 3. Абстракции, именование, документированиеСпецкурс 2014, занятие 3. Абстракции, именование, документирование
Спецкурс 2014, занятие 3. Абстракции, именование, документирование
 
Gang of four review.Structural patterns
Gang of four review.Structural patternsGang of four review.Structural patterns
Gang of four review.Structural patterns
 
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar..."The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...
"The SOLID software design principles" by Andrey Sklyarevsky from OK.RU at Ar...
 
C++ осень 2012 лекция 1
C++ осень 2012 лекция 1C++ осень 2012 лекция 1
C++ осень 2012 лекция 1
 
Чистая архитектура, Артур Бадретдинов АБЦТ
Чистая архитектура, Артур Бадретдинов АБЦТЧистая архитектура, Артур Бадретдинов АБЦТ
Чистая архитектура, Артур Бадретдинов АБЦТ
 
SOLID
SOLIDSOLID
SOLID
 
Design Principles
Design PrinciplesDesign Principles
Design Principles
 

Plus de beloslab

Mr. Keil Werner - Stem demo camp
Mr. Keil Werner - Stem demo campMr. Keil Werner - Stem demo camp
Mr. Keil Werner - Stem demo campbeloslab
 
Mr. Keil Werner - UOMO 2011
Mr. Keil Werner - UOMO 2011Mr. Keil Werner - UOMO 2011
Mr. Keil Werner - UOMO 2011beloslab
 
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0beloslab
 
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in developement
Konstantin Slisenko -  OSGi, Equinox, Eclipse plug-in developementKonstantin Slisenko -  OSGi, Equinox, Eclipse plug-in developement
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in developementbeloslab
 
Yuri Trukhin - IE9 Launch
Yuri Trukhin - IE9 LaunchYuri Trukhin - IE9 Launch
Yuri Trukhin - IE9 Launchbeloslab
 
Yuri Trukhin - Windows Phone 7
Yuri Trukhin - Windows Phone 7Yuri Trukhin - Windows Phone 7
Yuri Trukhin - Windows Phone 7beloslab
 
Sergey Gavruk - Mix11
Sergey Gavruk - Mix11Sergey Gavruk - Mix11
Sergey Gavruk - Mix11beloslab
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Frameworkbeloslab
 
Aleksei Gomza - ASP.NET MVC3 data processing
Aleksei Gomza - ASP.NET MVC3 data processingAleksei Gomza - ASP.NET MVC3 data processing
Aleksei Gomza - ASP.NET MVC3 data processingbeloslab
 
Aleksei Gomza - Web-applications and ASP
Aleksei Gomza - Web-applications and ASPAleksei Gomza - Web-applications and ASP
Aleksei Gomza - Web-applications and ASPbeloslab
 
Sergey Gavruk - WebMatrix
Sergey Gavruk - WebMatrixSergey Gavruk - WebMatrix
Sergey Gavruk - WebMatrixbeloslab
 
Konstantin slisenko - Design patterns
Konstantin slisenko - Design patternsKonstantin slisenko - Design patterns
Konstantin slisenko - Design patternsbeloslab
 

Plus de beloslab (12)

Mr. Keil Werner - Stem demo camp
Mr. Keil Werner - Stem demo campMr. Keil Werner - Stem demo camp
Mr. Keil Werner - Stem demo camp
 
Mr. Keil Werner - UOMO 2011
Mr. Keil Werner - UOMO 2011Mr. Keil Werner - UOMO 2011
Mr. Keil Werner - UOMO 2011
 
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in development, v 2.0
 
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in developement
Konstantin Slisenko -  OSGi, Equinox, Eclipse plug-in developementKonstantin Slisenko -  OSGi, Equinox, Eclipse plug-in developement
Konstantin Slisenko - OSGi, Equinox, Eclipse plug-in developement
 
Yuri Trukhin - IE9 Launch
Yuri Trukhin - IE9 LaunchYuri Trukhin - IE9 Launch
Yuri Trukhin - IE9 Launch
 
Yuri Trukhin - Windows Phone 7
Yuri Trukhin - Windows Phone 7Yuri Trukhin - Windows Phone 7
Yuri Trukhin - Windows Phone 7
 
Sergey Gavruk - Mix11
Sergey Gavruk - Mix11Sergey Gavruk - Mix11
Sergey Gavruk - Mix11
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Framework
 
Aleksei Gomza - ASP.NET MVC3 data processing
Aleksei Gomza - ASP.NET MVC3 data processingAleksei Gomza - ASP.NET MVC3 data processing
Aleksei Gomza - ASP.NET MVC3 data processing
 
Aleksei Gomza - Web-applications and ASP
Aleksei Gomza - Web-applications and ASPAleksei Gomza - Web-applications and ASP
Aleksei Gomza - Web-applications and ASP
 
Sergey Gavruk - WebMatrix
Sergey Gavruk - WebMatrixSergey Gavruk - WebMatrix
Sergey Gavruk - WebMatrix
 
Konstantin slisenko - Design patterns
Konstantin slisenko - Design patternsKonstantin slisenko - Design patterns
Konstantin slisenko - Design patterns
 

Yuri Trukhin - Software developement best practices

  • 1. Лучшие практики разработки ПО Принципы гибкого проектирования Юрий Трухин senior developer, CNIPGIS LLC Microsoft Student Partner Guru
  • 2. беларуская версія Лепшыя практыкі распрацоўкі праграмнага забеспячэння прынцыпы гнуткага праектавання Юрий Трухин senior developer, CNIPGIS LLC Microsoft Student Partner Guru
  • 4. Признаки плохого дизайна ПО Жесткость: дизайн трудно поддается изменению Хрупкость: дизайн легко разрушается Косность: дизайн трудно использовать повторно Вязкость: трудно добиться желаемого Ненужная сложность: избыточное проектирование Ненужные повторения: чрезмерное использование копирования и вставки Непрозрачность: плохо выраженная цель Часто эти признаки появляются в результате нарушения одного из принципов проектирования.
  • 6. public partial class Copier { public static void Copy() { int c; while ((c = Keyboard.Read()) != -1) { Printer.Write(c); } } }
  • 7. public class CopierWithPerfocards { /// <summary> /// не забудьте сбросить этот флаг /// </summary> private static boolptFlag = false; public static void Copy() { int c; while ((c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != -1) Printer.Write(c); } }
  • 8. public class CopierWithPerfocardsReadAndWrite { //не забудьте сбросить этот флаг public static boolptFlag = false; public static boolpunchFlag = false; public static void Copy() { int c; while ((c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != -1) punchFlag ? PaperTape.punchFlag(c) : Printer.Write(c); } }
  • 9. public interface Reader { int Read(); } public class KeyboardReader : Reader { public int Read() { return Keyboard.Read(); }; } public partial class Copier { public static Reader reader = new KeyboardReader(); public static void Copy() { var c; while ((c = (reader.Read())) != -1 ) { Printer.Write(c); } } }
  • 11. Принципы гибкого проектирования Принцип единственной обязанности Принцип открытости/закрытости Принцип подстановки Лисков Принцип инверсии зависимости Принцип разделения интерфейсов Принцип эквивалентности повторного использования и выпуска Принцип общей закрытости Принцип совместного повторного использования Принцип ацикличности зависимостей Принцип устойчивых зависимостей Принцип устойчивых абстракций
  • 12. Принцип единственной обязанности (SRP) «Никто кроме Будды не должен брать на себя ответственность за сокровенные знания» Э.Кобхэм Брюэр, 1897
  • 13. Принцип единственной обязанности (SRP) У класса должна быть только одна причина для изменения. Любое изменение требований проявляется в изменении распределения обязанностей между классами. Если класс берет на себя несколько обязанностей – у него появляется несколько причин для изменения. Если класс отвечает за несколько действий, его обязанности оказываются связанными. Это является причиной хрупкого дизайна приложений.
  • 14. Принцип единственной обязанности (SRP) Более одной обязанности Rectangle Приложение «Вычислительная геометрия» +draw() +area() : double Графическое приложение GUI
  • 16. Принцип единственной обязанности (SRP) Проблемы: В приложение «Вычислительная геометрия» попадает не нужная логика вместе с классом Rectangle. Если изменение графического приложения потребует изменить класс Rectangle, придется заново собирать, тестировать и развертывать приложение «Вычислительная геометрия». … или приложение «Вычислительная геометрия» неожиданно может перестать работать
  • 17. Принцип единственной обязанности (SRP) Обязанности разделены Rectangle GeometricRectangle Приложение «Вычислительная геометрия» Графическое приложение +draw() +area() : double GUI
  • 18. Принцип единственной обязанности (SRP) Обязанность – причина изменения Если вы можете найти несколько причин для изменения – у класса несколько обязанностей.
  • 19. Принцип единственной обязанности (SRP) Пример: Public interface Modem { public void Dial(string pno); public void Hangup(); public void Send (char c); public char Recv(); } Сколько обязанностей у интерфейса Modem?
  • 20. Принцип единственной обязанности (SRP) Сколько обязанностей?: Public interface Modem { public void Dial(string pno); //управление соединением public void Hangup();//управление соединением public void Send (char c);//передача данных public char Recv(); //передача данных } Нужно ли разделить интерфейс?
  • 21. Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: ДА! Если может потребоваться изменение сигнатуры методов управления соединением, класс, вызывающий send и receive придется повторно компилировать и развертывать чаще, чем хотелось бы. Это приводит к жесткости дизайна. Следует разделить интерфейс на DataChannelи Connection
  • 22. Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: НЕТ! Если приложение не модифицируют таким образом, что обязанности изменяются порознь, то разделять нет необходимости. Это приводит к излишней сложности. Изменения интерфейса не требуются.
  • 23. Принцип единственной обязанности (SRP) Нужно ли разделять интерфейс?: НЕТ! Если приложение не модифицируют таким образом, что обязанности изменяются порознь, то разделять нет необходимости. Это приводит к излишней сложности. Изменения интерфейса не требуются. Вывод: ось изменения становится таковой, если изменение имеет место. Если на то нет причин, неразумно применять ЛЮБОЙ принцип проектирования.
  • 24. Принцип единственной обязанности (SRP) Разделение связанных обязанностей. Обеспечение сохранности. Employee +CalculatePay +Store Persistense System Связь бизнес-правил и подсистемы сохраниния -> неприятности! Обычно тесты заставляют их разделять, если нет – в случае если появляется жесткость и хрупкость – нужен рефакторинг! (Для данного случая применимы паттерны Фасад, Объект доступа к данным, Прокси для разделения обязанностей).
  • 25. Принцип открытости-закрытости «Голланская дверь: существительное. Дверь, разделенная на две части по горизонтали так, что каждая створка может открываться и закрываться независимо» The American Heritage Dictionary of English language, 2000
  • 26. Принцип открытости-закрытости Программные сущности (классы, модули, функции) должны быть открыты для расширения и закрыты для модификации. Если единственное изменение в каком-то месте программы приводит к каскаду изменений в зависимых модулях – это признак жесткого дизайна.
  • 27. Принцип открытости-закрытости Основные храктеристики модулей, разработанных в соответствии с принципом открытости-закрытости: Они открыты для расширения (поведение модуля можно расширить, можно менять состав функций модуля). Они закрыты для модификации (расширение поведение модуля не сопряжено с изменением в исходном или двоичном коде модуля). Как это сделать?
  • 28. Принцип открытости-закрытости Как это сделать? С ПОМОЩЬЮ АБСТРАКЦИИ! Абстракция – абстрактный базовый класс, поведение – производный класс. Модуль, манипулирующий абстракцией можно сделать закрытым для модификации – он зависит от ФИКСИРОВАННОЙ абстракции. Модуль при этом остается расширяемым.
  • 29. Принцип открытости-закрытости Пример: Client Server Класс Client не является открытым и закрытым.
  • 30. Принцип открытости-закрытости Применив паттерн «Стратегия» получим: “interface” Client Interface Client Server Класс Client одновременно является открытым и закрытым.
  • 31. Принцип открытости-закрытости Альтернатива: Паттерн «Шаблонный метод» Открытые методы в policy реализуют некую политику, они аналогичны методам класса Client (описывают определенные функции в терминах абстрактных интерфейсов, часть класса policy, в C# это абстрактные методы, реализуются в подтипах policy). Поведения, описанные внутри policy, можно расширять и модифицировать. Policy Implementation +PolicyFunction() #ServiceFunction() #ServiceFunctiom
  • 33. Принцип открытости-закрытости --shape.h-------------------------------------------------------------------- enumShareType (circle, square); struct Shape { ShapeTypeitsType; } --circle.h------------------------------------------------------------------- struct Circle { ShapeTypeitsType; double itsRadius; Point itsCenter; }; void DrawCircle(struct Circle*); --square.h------------------------------------------------------------------- struct Square { ShapeTypeitsType; double itsSide; Point itsTopLeft; }; void DrawSquare(struct Square*);
  • 34. Принцип открытости-закрытости --drawAllShapes.cc----------------------------------------------------------- typedefstruct Shape *ShapePointer; //функция не может быть закрытой для добавления других фигур, //не удовлетворяет принципам OCP void DrawAllShapes(ShapePointer list[], int n) { int i; for (i=0; i<n; i++) { struct Shape* s = list[i]; switch (s->itsType) { case square: DrawSquare((struct Square*)s); break; case circle: DrawCircle((struct Circle*)s); break; } } } ///Резюме: ///это решение жесткое, ///тк после добавление фигуры Triange(треугольник) ///необходимо заново откомпилировать и развернуть файлы , содержащие опредлеление ///Shape, Square,Circle и DrawAllShapes. /// ///это решение хрупкое, ///т.к. есть много других switch/case и if/else, которые сложно отыскать и понять. /// ///это решение костное, потому что всякий, кто попытается использовать ///функцию DrawAllShapes в другой программе, вынужден будет тащить за собой ///определения Square и Circle, даже если в этой программе они не используются.
  • 35. Принцип открытости-закрытости public interface Shape { void Draw(); } public class Square : Shape { public void Draw() { //нарисовать квадрат } } public class Circle : Shape { public void Draw() { //нарисовать круг } } public void DrawAllShape(IList shapes) { foreach (Shape shape in shapes) shape.Draw(); }
  • 37. Принцип открытости-закрытости Изменившиеся требования Необходимо, чтобы все круги рисовались раньше всех квадратов.
  • 38. Принцип открытости-закрытости Вывод 1 Модель Shape не является естественной в системе, где упорядоченность связана с типом фигуры. Каким бы закрытым не был модуль, всегда найдется такое изменение, для которых он не закрыт. Не существует моделей, естественных во всех контекстах! Проектировщик должен решить, от каких изменений закрыть дизайн. OCP применим только с вероятными изменениями.
  • 39. Принцип открытости-закрытости Расстановка «точек подключения» «Обманул меня раз». Первоначально код пишется без учета возможных изменений. Если изменение происходят – реализуется абстракция, в будущем защищающие от подобного рода изменений. «Стимулирование изменений» Сначала пишем тесты. Разработку ведем очень короткими циклами, измеряемыми в днях, а не в неделях Разрабатываем содержательные функции до инфраструктуры и часто демонстрируем их заинтересованным сторонам Первую версию ПО выпускаем быстро, а последующие часто.
  • 40. Принцип открытости-закрытости Заключение Следование этому принципу позволит получить от ООП максимум обещанного: гибкость, возможность повторного использования и удобство сопровождения. Отказ от преждевременного абстрагирования столь же важен, как и само абстрагирование.
  • 41. Принцип подстановки лисков «Должна быть возможность вместо базового типа подставить любой его подтип»
  • 42. Принцип инверсии зависимостей Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
  • 43. Принцип разделения интерфейсов Клиенты не должны вынужденно зависеть от методов, которыми не пользуются.
  • 44. Принцип эквивалентности повторного использования и выпуска Единица повторного использования равна единице выпуска. (либо все классы, включенные в компонент можно повторно использовать, либо ни один!)
  • 45. Принцип общей закрытости Все классы внутри компонента должны быть закрыты относительно изменений одного и того же вида. Изменение, затрагивающее компонент, должно затрагивать все классы в этом компоненте и только в нем.
  • 46. Принцип совместного повторного использования Все классы внутри компонента используются совместно. Если вы можете повторно использовать один класс, то можете использовать и остальные.
  • 47. Принцип ацикличности зависимостей В графе зависимостей между компонентами не должно быть циклов
  • 48. Принцип устойчивых зависимостей Зависимости должны быть направлены в сторону устойчивости (изменяемые компоненты должны быть сверху графа, и из них собирается неизменяемый)
  • 49. Принцип устойчивых абстракций Компонент должен быть столь же абстрактным, сколь и устойчивым (иначе устойчивость будет препятствовать его расширению).
  • 50.
  • 51. Prism
  • 56.
  • 57. © 2008 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Notes de l'éditeur

  1. В приложение «Вычислительная геометрия» попадает не нужная логика вместе с классом Rectangle.Если изменение графического приложения потребует изменить класс Rectangle, придется заново собирать, тестировать и развертывать приложение «Вычислительная геометрия».… или приложение «Вычислительная геометрия» неожиданно может перестать работать
  2. ДА!Если может потребоваться изменение сигнатуры методов управления соединением, класс, вызывающий send и receive придется повторно компилировать и развертывать чаще, чем хотелось бы.Это приводит к жесткости дизайна. Следует разделить интерфейс на DataChannelи ConnectionНЕТ!Если приложение не модифицируют таким образом, что обязанности изменяются порознь, то разделять нет необходимости.Это приводит к излишней сложности. Изменения интерфейса не требуются.
  3. ///Резюме:///это решение жесткое,///тк после добавление фигуры Triange(треугольник)///необходимо заново откомпилировать и развернуть файлы , содержащие опредлеление///Shape, Square,Circle и DrawAllShapes.//////это решение хрупкое,///т.к. есть много других switch/case и if/else, которые сложно отыскать и понять.//////это решение костное, потому что всякий, кто попытается использовать ///функцию DrawAllShapes в другой программе, вынужден будет тащить за собой ///определения Square и Circle, даже если в этой программе они не используются.
  4. ///Резюме:///это решение жесткое,///тк после добавление фигуры Triange(треугольник)///необходимо заново откомпилировать и развернуть файлы , содержащие опредлеление///Shape, Square,Circle и DrawAllShapes.//////это решение хрупкое,///т.к. есть много других switch/case и if/else, которые сложно отыскать и понять.//////это решение костное, потому что всякий, кто попытается использовать ///функцию DrawAllShapes в другой программе, вынужден будет тащить за собой ///определения Square и Circle, даже если в этой программе они не используются.
  5. ///Резюме:///это решение жесткое,///тк после добавление фигуры Triange(треугольник)///необходимо заново откомпилировать и развернуть файлы , содержащие опредлеление///Shape, Square,Circle и DrawAllShapes.//////это решение хрупкое,///т.к. есть много других switch/case и if/else, которые сложно отыскать и понять.//////это решение костное, потому что всякий, кто попытается использовать ///функцию DrawAllShapes в другой программе, вынужден будет тащить за собой ///определения Square и Circle, даже если в этой программе они не используются.