design patterns part 1
TRANSCRIPT
![Page 1: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/1.jpg)
Шаблони проектування
Частина 1
![Page 2: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/2.jpg)
Coupling and cohesion
![Page 3: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/3.jpg)
Coupling (зв’язність)• Afferent– Скільки компонентів залежать від
модуля– Показує наскільки модуль
відповідальний
• Efferent– Від скількох компонентів залежить
модуль– Показує наскільки модуль
незалежний– Включає: наслідування, interface impl,
типи параметрів, типи змінних, exceptions,...
• Ca and Ce є метриками стабільності
![Page 4: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/4.jpg)
Instability
I = Ce / (Ce + Ca)
• показує нестійкість до змін• 0 – стабільний модуль• 1 – нестабільний
Ми залежимо від
Залежать від нас
![Page 5: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/5.jpg)
Cohesion (пов’язаність, зчеплення)
• Показує наскільки сильні взаємозв’язки між частинами одного модулю
• Чи всі методи класу використовують всі його поля
• Низька пов’язаність:– Клас з багатьма статичними
методами– “Несфокусований” клас
![Page 6: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/6.jpg)
Програмне забезпечення
• Успішне– Legacy (унаслідуване, застаріле)–Maintainable (легко підтримуване)
• Неуспішне
![Page 7: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/7.jpg)
Legacy software
• Довго експлуатується• Продовжує експлуатуватись• Задовільняє потреби замовника• Але разом з тим–Містить дефекти, не містить нових
функцій
• Важко покращується
![Page 8: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/8.jpg)
Maintainable software
• Довго експлуатується• Продовжує експлуатуватись• Задовільняє потреби замовника• Але разом з тим–Містить дефекти, не містить нових
функцій
• Легко покращується
![Page 9: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/9.jpg)
Бажані властивості
• Хочемо змінювати програму– Проясняються старі/з’являються нові
вимоги
• Не хочемо змінювати готові класи– Зміна – внесення нестабільності– Потрібно перетестувати– Залежності транзитивні
![Page 10: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/10.jpg)
Low coupling + high cohesion сприяють легкому внесенню змін у
ПЗ
Більшість шаблонів проектування є рецептами для зниження coupling
та підвищення cohesion
![Page 11: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/11.jpg)
Шаблони проектування
link link
![Page 12: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/12.jpg)
Створення об’єктів, creational patterns
![Page 13: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/13.jpg)
Dependencies
![Page 14: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/14.jpg)
public class Survey { public SurveyState State { get; set; } public DateTime StartDate { get; set; } public DateTime FinishDate { get; set; }
public void Start() { State = SurveyState.InProgress; try { var email = new SmtpEmailSender(); email.Send("Survey has started!", Constants.AdminEmail); } catch (SmtpException e) { ... } }}
![Page 15: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/15.jpg)
Survey
SmtpEmailSender
High level
module
Low level
module
Depends on
![Page 16: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/16.jpg)
public class Survey { private readonly IEmailSender _email; public SurveyState State { get; set; } public DateTime StartDate { get; set; } public DateTime FinishDate { get; set; }
public Survey(IEmailSender email) { _email = email; }
public void Start() { State = SurveyState.InProgress; try { _email.Send("Survey has started!", Constants.AdminEmail); } catch (SmtpException e) { ... } }}
![Page 17: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/17.jpg)
Survey
SmtpEmailSender
High level
module
IEmailSender
Implements
![Page 18: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/18.jpg)
Survey
SmtpEmailSender
IEmailSender
Application
![Page 19: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/19.jpg)
Survey
SmtpEmailSender
High level
module
IEmailSender
Dependency is inverted
![Page 20: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/20.jpg)
Dependency inversion
• High level modules should not depend on low-level modules
• Both should depend on abstractions• Abstractions should not depend on
details• Details should depend on
abstractions
![Page 21: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/21.jpg)
Що отримуємо• Залежності вказуються явно, немає
прихованих залежностей• Класи самодокументовані• Класи більше не відповідають за створення
об’єктів• Після створення клас гарантовано
знаходиться у робочому стані• Легко знаходити класи з багатьма
параметрами в конструкторі (і зменшувати їх відповідальності)
• Легше знаходити методи, яким потрібні не всі залежності класу
![Page 22: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/22.jpg)
Приклад
public void Import(){ var importContext = _contextCreator.Create(_userName); // ... _fileImporter.Import(); // ...}
![Page 23: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/23.jpg)
Прикладpublic void Import(){ var importContext = _contextCreator.Create(_userName); using (IFileImporter fileImporter = new FileImporter(importContext)) { fileImporter.Import(); }}
![Page 24: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/24.jpg)
Abstract Factory
![Page 25: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/25.jpg)
Потреба
• Залежність залежить від параметра, який не відомий клієнту на час його створення
• if/else та switch блоки для вирішення, яку залежність створити
• Залежність потрібно до-ініціалізувати
• Об’єкт повинен керувати часом життя залежності
![Page 26: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/26.jpg)
SurveyImporter
FileImporter
![Page 27: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/27.jpg)
SurveyImporter
FileImporter
IFileImporterFactory
IFileImporter
FileImporterFactory
![Page 28: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/28.jpg)
Реалізація
• Виклик конструктора об’єкта+ передача параметра+ передача створених/отриманих залежностей
• switch, Dictionary<TParameter, Func<TResult>>
![Page 29: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/29.jpg)
Часто фабрика повертає Null Object в default-вітці switch’а
public sealed class FileImporterFactory : IFileImporterFactory{ public IFileImporter Create(Context importContext) { switch (GetFileStorageType(importContext)) { case "csv": return new FileImporter(importContext, csvReader); case "xls": return new FileImporter(importContext, xlsReader); default: return new NullFileImporter(importContext); } }
![Page 30: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/30.jpg)
Null Object
![Page 31: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/31.jpg)
public SurveysImporter( IFileImporter headersFileImporter, IFileImporter dataFileImporter, IFileImporter additionalDataImporter){ if (headersFileImporter == null) { throw new ArgumentNullException("headersFileImporter"); } if (dataFileImporter == null) { throw new ArgumentNullException("dataFileImporter"); }
_headersFileImporter = headersFileImporter; _dataFileImporter = dataFileImporter; _additionalDataImporter = additionalDataImporter;}
Тут треба пояснюючий
коментар
![Page 32: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/32.jpg)
public void Import(){ _headersFileImporter.Import(); // ... _dataFileImporter.Import(); // ... if (_additionalDataImporter != null) { _additionalDataImporter.Import(); }}
Буде розмножуват
ись по вашому коду
![Page 33: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/33.jpg)
Потреба
• Код для NULL-випадку повинен бути ідентичним до решти випадків
![Page 34: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/34.jpg)
Реалізаціяpublic sealed class NullFileImporter : IFileImporter{ public void Import() { }}
public sealed class SurveysImporter{ public void Import() { _headersFileImporter.Import(); // ... _dataFileImporter.Import(); // ... _additionalDataImporter.Import();}
![Page 35: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/35.jpg)
Переваги
• Чистіший та стисліший код• Відсутність перевірок на null • Простіший код• Зменшення кількості
відповідальностей класів-клієнтів
![Page 36: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/36.jpg)
Builder
![Page 37: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/37.jpg)
Fluent Buildervar team = new Team( "Manchester United", "The Red Devils", Color.Red, "Manchester", "Old Trafford");
var builder = new TeamBuilder();var team = builder .CreateTeam("Real Madrid") .WithNickName("Los Merengues") .WithShirtColor(Color.White) .FromTown("Madrid") .PlayingAt("Santiago Bernabeu") .Build();
![Page 38: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/38.jpg)
Призначення
• Конструювання складного об’єкта• Відділення логіки конструювання
від представлення даних об’єкта
![Page 39: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/39.jpg)
Fluent Builder: Mocksvar workerPlanMock = new Mock<IWorkerPlan>();workerPlanMock .Setup(workerPlan => workerPlan.GetCountOfItemsToProcess()) .Returns(2);var worker = new Worker(workerPlanMock.Object);...
![Page 40: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/40.jpg)
StringBuilderStringBuilder builder = new StringBuilder();builder.Append("...");builder.AppendFormat("...{0}", "value") .AppendLine() .Append("...");string result = builder.ToString();
![Page 41: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/41.jpg)
SqlConnectionStringBuildervar builder = new SqlConnectionStringBuilder { DataSource = "localhost", InitialCatalog = "MyDB", IntegratedSecurity = true, ConnectTimeout = 10 // seconds };string connectionString = builder.ConnectionString;
![Page 42: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/42.jpg)
Lazy Instantiation
![Page 43: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/43.jpg)
Потреба public void Import(){ var importContext = _contextCreator.Create(_userName); if (ShouldReadFromFileSystem(importContext)) { FileImporter.Import(); }}
![Page 44: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/44.jpg)
Реалізація private IFileImporter _fileImporter;private readonly Func<IFileImporter> _fileImporterFactory;
private IFileImporter FileImporter{ get { if (_fileImporter == null) { _fileImporter = _fileImporterFactory(); } return _fileImporter; }}
![Page 45: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/45.jpg)
Призначення
• Відкладення створення об’єкта до моменту, коли об’єкт стає необхідний
• Оптимізація • Thread safety!
![Page 46: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/46.jpg)
Lazy<T>private readonly Lazy<IFileImporter> _fileImporter;
private IFileImporter FileImporter{ get { return _fileImporter.Value; }}
![Page 47: Design patterns part 1](https://reader035.vdocuments.site/reader035/viewer/2022062320/559282091a28ab44678b464e/html5/thumbnails/47.jpg)
Створення об’єктів• Coupling & Cohesion• Dependencies, Dependency
Inversion• Abstract Factory• Null Object• Fluent Builder• Lazy Instantiation