SlideShare une entreprise Scribd logo
1  sur  46
О принципах 
проектирования 
Сергей Тепляков
Обо мне 
• Microsoft C# MVP 2011-2014 
• MSFT Employee 2014- (VS Team) 
• Blogger: SergeyTeplyakov.blogspot.com 
• Контакты 
• Sergey.Teplyakov [sobak] gmail.com 
• @STeplyakov
О чем будем говорить? 
• О принципах проектирования в целом 
• О SOLID принципах
Нужны ли нам принципы проектирования?
Дизайн – штука сложная!
Поиск серебряной пули 
• Ответ на вопрос жизни вселенной и всего такого?
Мы хотим использовать опыт и знания 
повторно!
Классические подходы 
• Low coupling 
• High cohesion 
• Design by Contract
SOLID принципы 
• S – Single Responsibility Principle 
• O – Open-Closed Principle 
• L – Liskov Substitution Principle 
• I – Interface Segregation Principle 
• D – Dependency Inversion Principle
Опасности принципов 
• Что «сильнее» композиция или 
наследование? 
• Остерегайтесь культа карго
В чем проблема с текущим описанием? 
• Принципы слишком неформальны 
• Берут свое начало в 90-х (С++) 
• Не ясно, когда им следовать, а когда - 
нет
Как следовать этим принципам? 
Принципы существуют для того, чтобы помогать в 
устранении дурных запахов в дизайне. Это не духи, 
которыми надо обильно поливать всю систему. 
Чрезмерная приверженность принципам ведет к пороку 
ненужной сложности.
Single Responsibility Principle 
• Исходное определение: 
У класса должна быть только одна причина для изменения 
• Смысл принципа SRP: 
Борьба со сложностью 
• SRP violation means low cohesion! 
http://bit.ly/SingleResponsibilityPrinciple
Любой класс из реального мира будет 
нарушать SRP
Типичные примеры нарушения SRP
Смешивание логики и инфраструктуры 
• Windows сервис ходит в базу 
• WCF-сервис сам содержит логику обработки 
запросов 
• Azure Role содержит логику по 
перекладыванию данных из одного места в 
другое. 
• Смешивание логики и «сохраняемости» 
(persistence)
Смешивание логики и представления
Выделяйте каждому сложному аспекту 
системы свой класс/модуль
Я хочу иметь возможность сосредоточиться на 
сложных аспектах системы по отдельности, 
поэтому когда мне становится сложно это 
делать, я начинаю разбивать классы и выделять 
новые.
Дизайн – это эволюционный процесс
Актуальность SRP возрастает вместе с 
увеличением сложности!
Пример увеличения сложности: добавление 
предусловий
Интерфейс ContextActionBase 
public abstract class ContextActionBase 
{ 
public abstract void Execute(); 
public abstract bool IsAvailable(); 
public abstract string Text { get; } 
}
Эволюция дизайна
SRP – это способ поиска скрытых абстракций, 
достаточно сложных, чтобы им отвели 
отдельную именованную сущность и спрятали в 
их недрах все детали.
Open-Closed Principle 
Классы, модули, функции и т.п.) должны быть 
открытыми для расширения, но закрытыми для 
модификации 
http://bit.ly/OpenClosedPrinciple
Как вы понимаете OCP?
Объяснение Боба Мартина 
• Они открыты для расширения. Это означает, что поведение модуля можно 
расширить. Когда требования к приложению изменяются, мы добавляем в 
модуль новое поведение, отвечающее изменившимся требованиям. Иными 
словами, мы можем изменить состав функций модуля. 
• Они закрыты для модификации. Расширение поведения модуля не 
сопряжено с изменениями в исходном или двоичном коде модуля. Двоичное 
исполняемое представление модуля, будь то компонуемая библиотека, DLL 
или EXE-файл, остается неизменным (выделено мною).
Нарушает ли фабрика OCP? 
abstract class Importer 
{ 
public abstract void ImportData(); 
} 
static class ImporterFactory 
{ 
public static Importer Create(string fileName) 
{ 
var extension = Path.GetExtension(fileName); 
switch (extension) 
{ 
case "json": 
return new JsonImporter(); 
case "xls": 
case "xlsx": 
return new XlsImporter(); 
default: 
throw new InvalidOperationException("Extension is not supported"); 
} 
} 
}
Принцип единственного выбора 
Всякий раз, когда система программного обеспечения 
должна поддерживать множество альтернатив, их 
полный список должен быть известен только одному 
модулю системы. 
Бербран Мейер
OCP != Расширяемость
Определение от Бертрана Мейера 
• Модуль называют открытым, если он еще доступен для расширения. 
Например, имеется возможность расширить множество операций в нем или 
добавить поля к его структурам данных. 
• Модуль называют закрытым, если он доступен для использования другими 
модулями. Это означает, что модуль (его интерфейс – с точки зрения скрытия 
информации) уже имеет строго определенное окончательное описание. На 
уровне реализации закрытое состояние модуля означает, что модуль можно 
компилировать, сохранять в библиотеке и делать его доступным для 
использования другими модулями (его клиентами).
Open-Closed Principle 
• Что такое OCP? Это фиксация интерфейса класса/модуля, и 
возможность изменения или подмены реализации/поведения. 
• Цели OCP: борьба со сложностью и ограничение изменений 
минимальным числом модулей. 
• Как мы реализуем OCP? С помощью инкапсуляции, которая позволяет 
изменять реализацию без изменения интерфейса и с помощью 
наследования, что позволяет заменить реализацию, которая не 
затронет существующих клиентов базового класса.
Типичный пример нарушения 
расширяемости (OCP) 
public static int Count<TSource>(this IEnumerable<TSource> source) 
{ 
var collectionoft = source as ICollection<TSource>; 
if (collectionoft != null) return collectionoft.Count; 
var collection = source as ICollection; 
if (collection != null) return collection.Count; 
int count = 0; 
using (IEnumerator<TSource> e = source.GetEnumerator()) 
{ 
while (e.MoveNext()) count++; 
} 
return count; 
}
Расширяемость: OOP vs. FP 
• В ООП: легко добавлять новый тип, сложно – новую операцию 
• В ФП: легко добавлять новую операцию, сложно – новый тип 
Expression Problem!
Расширяемость в ООП
Иногда мы хотим вынести логику за пределы 
иерархии! 
Решение: Посетитель!
Пример
public interface IValidationResultVisitor 
{ 
void Visit(NoErrorValidationResult vr); 
void Visit(ContractErrorValidationResult vr); 
void Visit(ContractWarningValidationResult vr); 
void Visit(CustomWarningValidationResult vr); 
} 
public abstract class ValidationResult 
{ 
private ICSharpStatement _statement; 
protected ValidationResult(ICSharpStatement statement) 
{ 
Contract.Requires(statement != null); 
_statement = statement; 
} 
public abstract void Accept(IValidationResultVisitor visitor); 
}
class IsIssueFixableVisitor : IValidationResultVisitor 
{ 
public bool IsIssueFixable { get; private set; } 
public void Visit(NoErrorValidationResult vr) 
{ 
IsIssueFixable = false; 
} 
public void Visit(ContractErrorValidationResult vr) 
{ 
IsIssueFixable = 
vr.Error == MalformedContractError.VoidReturnMethodCall; 
} 
public void Visit(ContractWarningValidationResult vr) 
{ 
IsIssueFixable = 
vr.Warning == MalformedContractWarning.NonVoidReturnMethodCall; 
} 
public void Visit(CustomWarningValidationResult vr) 
{ 
IsIssueFixable = false; 
} 
}
ФП подход: сопоставление с образцом 
public T Match<T>( 
Func<CodeContractErrorValidationResult, T> errorMatch, 
Func<CodeContractWarningValidationResult, T> warningMatch, 
Func<ValidationResult, T> defaultMatch) 
{ 
var errorResult = this as CodeContractErrorValidationResult; 
if (errorResult != null) 
return errorMatch(errorResult); 
var warningResult = this as CodeContractWarningValidationResult; 
if (warningResult != null) 
return warningMatch(warningResult); 
return defaultMatch(this); 
}
Пример использования 
ValidationResult vr = GetValidationResult(); 
bool isFixable = vr.Match( 
error => error.Error == 
MalformedContractError.VoidReturnMethodCall, 
warning => warning.Warning == 
MalformedContractWarning.NonVoidReturnMethodCall, 
@default => false);
Как пользуюсь принципами? 
• Принципы – не самоцель! 
• Дизайн постоянно эволюционирует. Валидируйте его согласно этим 
принципам на каждой итерации.
Цикл постов о SOLID-принципах 
• http://bit.ly/SingleResponsibilityPrinciple 
• http://bit.ly/OpenClosedPrinciple 
• http://bit.ly/LiskovSubstitutionPrinciple 
• http://bit.ly/InterfaceSegregationPrinciple 
• http://bit.ly/DependencyInversionPrinciple
Чего почитать по теме 
• О культе карго в программировании 
sergeyteplyakov.blogspot.com/2013/09/blog-post_24.html 
• Критика книги Боба Мартина «Принципы, паттерны и методики гибкой 
разработки на языке C#» 
sergeyteplyakov.blogspot.com/2013/12/about-agile-principles-patterns-and.html 
• Цикл постов об управлении зависимостями 
http://sergeyteplyakov.blogspot.com/2013/10/articles.html#dependency_manage 
ment 
• Лучшая книга по ООП эвар! – Бертран Мейер «Объектно-ориентированное 
конструирование программных систем» 
http://sergeyteplyakov.blogspot.com/2012/03/blog-post_19.html

Contenu connexe

Tendances

Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайнаПринципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
Сергей Шебанин
 
Шаблоны разработки ПО. Шаблоны GRASP
Шаблоны разработки ПО. Шаблоны GRASPШаблоны разработки ПО. Шаблоны GRASP
Шаблоны разработки ПО. Шаблоны GRASP
Sergey Nemchinsky
 
SOLID & GRASP
SOLID & GRASPSOLID & GRASP
SOLID & GRASP
devel123
 
Шаблоны разработки ПО. Часть 2. ООП и UML
Шаблоны разработки ПО. Часть 2. ООП и UMLШаблоны разработки ПО. Часть 2. ООП и UML
Шаблоны разработки ПО. Часть 2. ООП и UML
Sergey Nemchinsky
 
Msu.Center.Lectures.J03 Oop And Uml
Msu.Center.Lectures.J03 Oop And UmlMsu.Center.Lectures.J03 Oop And Uml
Msu.Center.Lectures.J03 Oop And Uml
olegol
 
Java. Lecture 03. OOP and UML
Java. Lecture 03. OOP and UMLJava. Lecture 03. OOP and UML
Java. Lecture 03. OOP and UML
colriot
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5
Technopark
 

Tendances (20)

Классы и объекты С#
Классы и объекты С#Классы и объекты С#
Классы и объекты С#
 
Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.Большие проекты, архитектура и фреймворки.
Большие проекты, архитектура и фреймворки.
 
Принципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайнаПринципы объектно-ориентированного дизайна
Принципы объектно-ориентированного дизайна
 
Шаблоны разработки ПО. Шаблоны GRASP
Шаблоны разработки ПО. Шаблоны GRASPШаблоны разработки ПО. Шаблоны GRASP
Шаблоны разработки ПО. Шаблоны GRASP
 
Step 3.1
Step 3.1Step 3.1
Step 3.1
 
SOLID
SOLIDSOLID
SOLID
 
Uml
UmlUml
Uml
 
Составные части объектного подхода
Составные части объектного подходаСоставные части объектного подхода
Составные части объектного подхода
 
Шаблоны проектирования GoF
Шаблоны проектирования GoFШаблоны проектирования GoF
Шаблоны проектирования GoF
 
SOLID & GRASP
SOLID & GRASPSOLID & GRASP
SOLID & GRASP
 
Интерфейсы
ИнтерфейсыИнтерфейсы
Интерфейсы
 
Refactoring
RefactoringRefactoring
Refactoring
 
Java core-lect6-part3-annotation.ppt
Java core-lect6-part3-annotation.pptJava core-lect6-part3-annotation.ppt
Java core-lect6-part3-annotation.ppt
 
Шаблоны разработки ПО. Часть 2. ООП и UML
Шаблоны разработки ПО. Часть 2. ООП и UMLШаблоны разработки ПО. Часть 2. ООП и UML
Шаблоны разработки ПО. Часть 2. ООП и UML
 
Java Core. Lecture# 2. Classes & objects.
Java Core. Lecture# 2. Classes & objects.Java Core. Lecture# 2. Classes & objects.
Java Core. Lecture# 2. Classes & objects.
 
Msu.Center.Lectures.J03 Oop And Uml
Msu.Center.Lectures.J03 Oop And UmlMsu.Center.Lectures.J03 Oop And Uml
Msu.Center.Lectures.J03 Oop And Uml
 
Java. Lecture 03. OOP and UML
Java. Lecture 03. OOP and UMLJava. Lecture 03. OOP and UML
Java. Lecture 03. OOP and UML
 
JUnit, дай пять!
JUnit, дай пять!JUnit, дай пять!
JUnit, дай пять!
 
Наследование и полиморфизм
Наследование и полиморфизмНаследование и полиморфизм
Наследование и полиморфизм
 
C++ осень 2013 лекция 5
C++ осень 2013 лекция 5C++ осень 2013 лекция 5
C++ осень 2013 лекция 5
 

En vedette (6)

SOLID
SOLIDSOLID
SOLID
 
Solid code via tdd
Solid code via tddSolid code via tdd
Solid code via tdd
 
Android architecture
Android architectureAndroid architecture
Android architecture
 
Android Architecture
Android ArchitectureAndroid Architecture
Android Architecture
 
Сергей Калинец "Не SQL-ом единым..."
Сергей Калинец "Не SQL-ом единым..."Сергей Калинец "Не SQL-ом единым..."
Сергей Калинец "Не SQL-ом единым..."
 
android architecture
android architectureandroid architecture
android architecture
 

Similaire à SOLID Principles in the real world

Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practices
beloslab
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011
etyumentcev
 
C++ осень 2012 лекция 1
C++ осень 2012 лекция 1C++ осень 2012 лекция 1
C++ осень 2012 лекция 1
Technopark
 

Similaire à SOLID Principles in the real world (20)

разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
разработка бизнес приложений (6)
разработка бизнес приложений (6)разработка бизнес приложений (6)
разработка бизнес приложений (6)
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
 
SOLID
SOLIDSOLID
SOLID
 
Yuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practicesYuri Trukhin - Software developement best practices
Yuri Trukhin - Software developement best practices
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharp
 
Автоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharpАвтоматизация design patterns и компактный код вместе с PostSharp
Автоматизация design patterns и компактный код вместе с PostSharp
 
PostSharp - Threading Model
PostSharp - Threading ModelPostSharp - Threading Model
PostSharp - Threading Model
 
PostSharp - Threading Model Library
PostSharp - Threading Model LibraryPostSharp - Threading Model Library
PostSharp - Threading Model Library
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011
 
Aspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design PatternsAspect Oriented Programming and Design Patterns
Aspect Oriented Programming and Design Patterns
 
AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)AOP and Design Patterns (GoF)
AOP and Design Patterns (GoF)
 
Принципы Solid на практике
Принципы Solid на практикеПринципы Solid на практике
Принципы Solid на практике
 
C++ осень 2012 лекция 1
C++ осень 2012 лекция 1C++ осень 2012 лекция 1
C++ осень 2012 лекция 1
 
Tdd php
Tdd phpTdd php
Tdd php
 
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПОЕвгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
Евгений Кривошеев: Фундаментальные правила и принципы проектирования ПО
 
Design Rules And Principles
Design Rules And PrinciplesDesign Rules And Principles
Design Rules And Principles
 
FlatGUI: Reactive GUI Toolkit Implemented in Clojure
FlatGUI: Reactive GUI Toolkit Implemented in ClojureFlatGUI: Reactive GUI Toolkit Implemented in Clojure
FlatGUI: Reactive GUI Toolkit Implemented in Clojure
 
Design principles
Design principles Design principles
Design principles
 

Plus de EPAM

Plus de EPAM (9)

JavaScript. Code Quality.
JavaScript. Code Quality.JavaScript. Code Quality.
JavaScript. Code Quality.
 
Continuous integration for JavaScript projects
Continuous integration for JavaScript projectsContinuous integration for JavaScript projects
Continuous integration for JavaScript projects
 
Visualization of Big Data in Web Apps
Visualization of Big Data in Web AppsVisualization of Big Data in Web Apps
Visualization of Big Data in Web Apps
 
Object Oriented Concepts in Real Projects
Object Oriented Concepts in Real ProjectsObject Oriented Concepts in Real Projects
Object Oriented Concepts in Real Projects
 
Modern web applications infrastructure
Modern web applications infrastructureModern web applications infrastructure
Modern web applications infrastructure
 
Reactive Extensions: classic Observer in .NET
Reactive Extensions: classic Observer in .NETReactive Extensions: classic Observer in .NET
Reactive Extensions: classic Observer in .NET
 
Future of the Future of E-Commerce
Future of the Future of E-CommerceFuture of the Future of E-Commerce
Future of the Future of E-Commerce
 
Bootify Yyour App from Zero to Hero
Bootify Yyour App from Zero to HeroBootify Yyour App from Zero to Hero
Bootify Yyour App from Zero to Hero
 
Responsive Web in Brief
Responsive Web in BriefResponsive Web in Brief
Responsive Web in Brief
 

SOLID Principles in the real world

  • 2. Обо мне • Microsoft C# MVP 2011-2014 • MSFT Employee 2014- (VS Team) • Blogger: SergeyTeplyakov.blogspot.com • Контакты • Sergey.Teplyakov [sobak] gmail.com • @STeplyakov
  • 3. О чем будем говорить? • О принципах проектирования в целом • О SOLID принципах
  • 4. Нужны ли нам принципы проектирования?
  • 5. Дизайн – штука сложная!
  • 6. Поиск серебряной пули • Ответ на вопрос жизни вселенной и всего такого?
  • 7. Мы хотим использовать опыт и знания повторно!
  • 8. Классические подходы • Low coupling • High cohesion • Design by Contract
  • 9. SOLID принципы • S – Single Responsibility Principle • O – Open-Closed Principle • L – Liskov Substitution Principle • I – Interface Segregation Principle • D – Dependency Inversion Principle
  • 10. Опасности принципов • Что «сильнее» композиция или наследование? • Остерегайтесь культа карго
  • 11. В чем проблема с текущим описанием? • Принципы слишком неформальны • Берут свое начало в 90-х (С++) • Не ясно, когда им следовать, а когда - нет
  • 12. Как следовать этим принципам? Принципы существуют для того, чтобы помогать в устранении дурных запахов в дизайне. Это не духи, которыми надо обильно поливать всю систему. Чрезмерная приверженность принципам ведет к пороку ненужной сложности.
  • 13. Single Responsibility Principle • Исходное определение: У класса должна быть только одна причина для изменения • Смысл принципа SRP: Борьба со сложностью • SRP violation means low cohesion! http://bit.ly/SingleResponsibilityPrinciple
  • 14. Любой класс из реального мира будет нарушать SRP
  • 16. Смешивание логики и инфраструктуры • Windows сервис ходит в базу • WCF-сервис сам содержит логику обработки запросов • Azure Role содержит логику по перекладыванию данных из одного места в другое. • Смешивание логики и «сохраняемости» (persistence)
  • 17. Смешивание логики и представления
  • 18. Выделяйте каждому сложному аспекту системы свой класс/модуль
  • 19. Я хочу иметь возможность сосредоточиться на сложных аспектах системы по отдельности, поэтому когда мне становится сложно это делать, я начинаю разбивать классы и выделять новые.
  • 20. Дизайн – это эволюционный процесс
  • 21. Актуальность SRP возрастает вместе с увеличением сложности!
  • 22. Пример увеличения сложности: добавление предусловий
  • 23. Интерфейс ContextActionBase public abstract class ContextActionBase { public abstract void Execute(); public abstract bool IsAvailable(); public abstract string Text { get; } }
  • 24.
  • 26. SRP – это способ поиска скрытых абстракций, достаточно сложных, чтобы им отвели отдельную именованную сущность и спрятали в их недрах все детали.
  • 27. Open-Closed Principle Классы, модули, функции и т.п.) должны быть открытыми для расширения, но закрытыми для модификации http://bit.ly/OpenClosedPrinciple
  • 29. Объяснение Боба Мартина • Они открыты для расширения. Это означает, что поведение модуля можно расширить. Когда требования к приложению изменяются, мы добавляем в модуль новое поведение, отвечающее изменившимся требованиям. Иными словами, мы можем изменить состав функций модуля. • Они закрыты для модификации. Расширение поведения модуля не сопряжено с изменениями в исходном или двоичном коде модуля. Двоичное исполняемое представление модуля, будь то компонуемая библиотека, DLL или EXE-файл, остается неизменным (выделено мною).
  • 30. Нарушает ли фабрика OCP? abstract class Importer { public abstract void ImportData(); } static class ImporterFactory { public static Importer Create(string fileName) { var extension = Path.GetExtension(fileName); switch (extension) { case "json": return new JsonImporter(); case "xls": case "xlsx": return new XlsImporter(); default: throw new InvalidOperationException("Extension is not supported"); } } }
  • 31. Принцип единственного выбора Всякий раз, когда система программного обеспечения должна поддерживать множество альтернатив, их полный список должен быть известен только одному модулю системы. Бербран Мейер
  • 33. Определение от Бертрана Мейера • Модуль называют открытым, если он еще доступен для расширения. Например, имеется возможность расширить множество операций в нем или добавить поля к его структурам данных. • Модуль называют закрытым, если он доступен для использования другими модулями. Это означает, что модуль (его интерфейс – с точки зрения скрытия информации) уже имеет строго определенное окончательное описание. На уровне реализации закрытое состояние модуля означает, что модуль можно компилировать, сохранять в библиотеке и делать его доступным для использования другими модулями (его клиентами).
  • 34. Open-Closed Principle • Что такое OCP? Это фиксация интерфейса класса/модуля, и возможность изменения или подмены реализации/поведения. • Цели OCP: борьба со сложностью и ограничение изменений минимальным числом модулей. • Как мы реализуем OCP? С помощью инкапсуляции, которая позволяет изменять реализацию без изменения интерфейса и с помощью наследования, что позволяет заменить реализацию, которая не затронет существующих клиентов базового класса.
  • 35. Типичный пример нарушения расширяемости (OCP) public static int Count<TSource>(this IEnumerable<TSource> source) { var collectionoft = source as ICollection<TSource>; if (collectionoft != null) return collectionoft.Count; var collection = source as ICollection; if (collection != null) return collection.Count; int count = 0; using (IEnumerator<TSource> e = source.GetEnumerator()) { while (e.MoveNext()) count++; } return count; }
  • 36. Расширяемость: OOP vs. FP • В ООП: легко добавлять новый тип, сложно – новую операцию • В ФП: легко добавлять новую операцию, сложно – новый тип Expression Problem!
  • 38. Иногда мы хотим вынести логику за пределы иерархии! Решение: Посетитель!
  • 40. public interface IValidationResultVisitor { void Visit(NoErrorValidationResult vr); void Visit(ContractErrorValidationResult vr); void Visit(ContractWarningValidationResult vr); void Visit(CustomWarningValidationResult vr); } public abstract class ValidationResult { private ICSharpStatement _statement; protected ValidationResult(ICSharpStatement statement) { Contract.Requires(statement != null); _statement = statement; } public abstract void Accept(IValidationResultVisitor visitor); }
  • 41. class IsIssueFixableVisitor : IValidationResultVisitor { public bool IsIssueFixable { get; private set; } public void Visit(NoErrorValidationResult vr) { IsIssueFixable = false; } public void Visit(ContractErrorValidationResult vr) { IsIssueFixable = vr.Error == MalformedContractError.VoidReturnMethodCall; } public void Visit(ContractWarningValidationResult vr) { IsIssueFixable = vr.Warning == MalformedContractWarning.NonVoidReturnMethodCall; } public void Visit(CustomWarningValidationResult vr) { IsIssueFixable = false; } }
  • 42. ФП подход: сопоставление с образцом public T Match<T>( Func<CodeContractErrorValidationResult, T> errorMatch, Func<CodeContractWarningValidationResult, T> warningMatch, Func<ValidationResult, T> defaultMatch) { var errorResult = this as CodeContractErrorValidationResult; if (errorResult != null) return errorMatch(errorResult); var warningResult = this as CodeContractWarningValidationResult; if (warningResult != null) return warningMatch(warningResult); return defaultMatch(this); }
  • 43. Пример использования ValidationResult vr = GetValidationResult(); bool isFixable = vr.Match( error => error.Error == MalformedContractError.VoidReturnMethodCall, warning => warning.Warning == MalformedContractWarning.NonVoidReturnMethodCall, @default => false);
  • 44. Как пользуюсь принципами? • Принципы – не самоцель! • Дизайн постоянно эволюционирует. Валидируйте его согласно этим принципам на каждой итерации.
  • 45. Цикл постов о SOLID-принципах • http://bit.ly/SingleResponsibilityPrinciple • http://bit.ly/OpenClosedPrinciple • http://bit.ly/LiskovSubstitutionPrinciple • http://bit.ly/InterfaceSegregationPrinciple • http://bit.ly/DependencyInversionPrinciple
  • 46. Чего почитать по теме • О культе карго в программировании sergeyteplyakov.blogspot.com/2013/09/blog-post_24.html • Критика книги Боба Мартина «Принципы, паттерны и методики гибкой разработки на языке C#» sergeyteplyakov.blogspot.com/2013/12/about-agile-principles-patterns-and.html • Цикл постов об управлении зависимостями http://sergeyteplyakov.blogspot.com/2013/10/articles.html#dependency_manage ment • Лучшая книга по ООП эвар! – Бертран Мейер «Объектно-ориентированное конструирование программных систем» http://sergeyteplyakov.blogspot.com/2012/03/blog-post_19.html

Notes de l'éditeur

  1. Молодые разработчики и менеджеры стараются найти ответ на вопрос жизни
  2. Сказать о фабриках!