SlideShare a Scribd company logo
Шаблони
проектування
  Частина 2
Розглянемо
•   Presentation pattern Model View Presenter
•   Шаблони поведінки
•   Структурні шаблони
•   Деякі вже відомі нам шаблони
Model View Presenter
Призначення
Розділення
• Даних для показу
• Логіки програми
• Відображення даних
Сповіщає Presenter          displays
      про дії
   користувача,
 відображає дані
                                                     Дані для показу
                          updates

                View                      Model


   change
   request             Presenter                        fetches


                               Завантажує дані, передає дані на
                                View, реагує на дії користувача
View                Model



       Presenter
                             UI


  Domain       Data Access
Відповідальності: Model
•   Контейнер для даних для відображення
•   Supervising Controller: View знає про Модель
•   Passive View: View не знає про Модель
•   Також може бути класом з предметної області
Відповідальності: View
• Є формою, показує UI
• Створює Презентер, передає себе йому
• Перенаправляє дії користувача Презентеру
• Може знати про Модель
• Або може надавати детальний інтерфейс для
  встановлення даних
• Звертається до конкретного Презентера
Відповідальності: Presenter
• Реагує на дії користувача
• Оновлює View даними з Моделі
• Позбавляє View відповідальності за логіку та
  взаємодію з бізнес-класами та data access
  – Презентер отримує дані з бізнес-рівня
  – Трансформація/фільтрування даних
  – Презентер зберігає зміни, зроблені користувачем
• Звертається до View через інтерфейс IView
Модифікації
• Supervising Controller
  – View відповідає за data binding Моделі
  – Презентер передає Модель на View
  – Презентер керує складнішими взаємодіями
• Passive View
  – Презентер відповідає за передачу кожної
    частини даних на View
  – View лише відображає передані прості дані
Застосовується
• Windows Forms
  – Існують розвинені MVP фреймворки
• ASP.NET Web Forms
Strategy
public sealed class SurveysImporter {
    public void Import() {
        // ... initialize import here
        switch (GetFileStorageType(importContext)) {
            case SurveysStorageType.Xls:
                ImportFromExcel();
                break;
            case SurveysStorageType.Csv:
                ImportFromCsvFile();
                break;
            case ...
            default:
                DoNothingButLog();
                break;
        }
        // ... report import completed successfully
    }
public sealed class SurveysImporterWithStrategy
{
    private readonly IFileImporterStrategy
        fileImporterStrategy;

   public void Import()
   {
       // ... initialize import here
       fileImporterStrategy.Import();
       // ... report import completed successfully
   }
Призначення
• Інкапсуляція алгоритму
• Зміна та розвиток алгоритму окремо від
  клієнта
• Винесення наборів різної поведінки з класу
• Усунення умовних операторів
• Уникнення зміни класу при додаванні
  нового алгоритму
Реалізація
• Створення класу-стратегії для кожної
  варіації алгоритму
• Створення спільного інтерфейсу для всіх
  цих алгоритмів
• Стратегія може використовувати клас-
  клієнт
• Або інший контекст
public class FilesSender
{
    public void SendToServer(Directory directory, Context context)
    {
        if (context.SendTopLevelFilesFirst)
        {
            foreach (var file in directory.Files)
            {
                SendToServer(file);
            }
            foreach (var childDirectory in directory.Directories)
            {
                SendToServer(childDirectory, context);
            }
        }
Higher order functions
• Є стратегіями
public class FilesSender
{
    private readonly
       Func<Directory, IEnumerable<File>> enumerateFiles;

   public FilesSenderWithStrategy(
        Func<Directory, IEnumerable<File>> directoryTraverser)
   {
       enumerateFiles = directoryTraverser;
   }

   public void SendToServer(Directory directory, Context context)
   {

       foreach (var file in   enumerateFiles(directory))
       {
           SendToServer(file);
       }
   }
Template Method
public class SurveysImporter
{
    public void Import()
    {
        InitializeImport();
        DoImport();
        NotifyUsers();
        ReportSuccessfullCompletion();
    }
public class CsvSurveysImporter :
    SurveysImporterWithTemplateMethod
{
    protected override void DoImport()
    {
        // CSV import implementation here
    }

    protected override void NotifyUsers()
    {
        // users notification implementation here
    }
}
Призначення
• Алгоритм складається з декількох кроків
• Реалізація одного кроку може змінюватись
• (або декількох кроків)
• Інкапсуляція незмінної послідовності кроків
• Можливість задати реалізацію кроків, що можуть
  змінюватись
• Зміна кроків алгоритму без зміни його структури
Реалізація
• Підкласи перевизначають окремі кроки
  алгоритму, визначеного в базовому класі
• Базується на наслідуванні
• Альтернатива – Strategy
Приклад
• ASP.NET page lifecycle
  – OnInit(), OnLoad() etc.
Command
private void Import(Survey survey)
{
    if (survey.CreatedBy == currentUser &&
        survey.CreatedOn < DateTime.Today &&
        (
            new[] { SurveyState.New, SurveyState.Finished }
                .Contains(survey.State) ||
            survey.State == SurveyState.Paused &&
              !survey.HasAnswers
        ) &&
        !AlreadyExistsSurveyWithTitle(survey.Title))
    {
        // create new or update existing survey
    }
}
Призначення
• Представлення дії як об’єкта
• Відділення виконання дії від деталей і
  залежностей, необхідних для реалізації дії
• Додавання нових дій без зміни клієнтів
public interface ICommand
{
    void Execute();
}                    Не приймає
                       аргументів


public interface ICommand<T>
{
    void ExecuteFor(T obj);
}
public class ImportSurveyCommand : ICommand<Survey>
{
    private readonly string currentUser;
    private readonly object importContext;

    public ImportSurveyCommand(string currentUser,
        object importContext)
    {
        this.currentUser = currentUser;
        this.importContext = importContext;
    }

    public void ExecuteFor(Survey obj)
    {
        // create new or update existing survey
    }
}
private void Import(Survey survey)
{
  if (survey.CreatedBy == currentUser &&
      ...)
  {
      var importSurvey = new ImportSurveyCommand(
           currentUser,
           GetImportContext());
      importSurvey.ExecuteFor(survey);
  }
}
Команда може використовуватись для
       undo функціональності
public interface ICommand
{
    bool CanExecute();
    void Execute();
    void Undo();
}
Specification
private void Import(Survey survey)
{
    if (survey.CreatedBy == currentUser &&
        survey.CreatedOn < DateTime.Today &&
        (
            new[] { SurveyState.New, SurveyState.Finished }
                .Contains(survey.State) ||
            survey.State == SurveyState.Paused &&
              !survey.HasAnswers
        ) &&
        !AlreadyExistsSurveyWithTitle(survey.Title))
    {
        // create new or update existing survey
    }
}
Передумови
•   Бізнес-правило містить багато коду
•   Правило логічно складне
•   Правило може часто змінюватись
•   Правил може бути декілька

• Призначення: спрощення коду класу-клієнта
public interface ISpecification<T>
{
    bool IsSatisfiedBy(T obj);
}


public class SurveyShouldBeImported :
    ISpecification<Survey>
{
    public bool IsSatisfiedBy(Survey obj)
    {
        // ...
    }
}
Реалізація
• Інкапсулює булеве бізнес-правило
• Можливі композитні Специфікації
  – AndSpecification, OrSpecification,
    NotSpecification
• Можливе поєднання Команд та
  Специфікацій
public class AndSpecification<T> : ISpecification<T>
{
    private readonly ISpecification<T> first;
    private readonly ISpecification<T> second;

    public AndSpecification(ISpecification<T> first,
        ISpecification<T> second)
    {
        this.first = first;
        this.second = second;
    }

    public bool IsSatisfiedBy(T obj)
    {
        return first.IsSatisfiedBy(obj) &&
            second.IsSatisfiedBy(obj);
    }
}
Adapter
Призначення
• Класи-клієнти використовують певний
  інтерфейс
• Потрібне перетворення інтерфейсу одного
  класу в інтерфейс іншого
• Для використання існуючих класів
• Адаптує один інтерфейс до іншого
Приклад
public interface ISurveyRepository
{
    IList<Survey> GetAll();
    Survey Get(int id);
}
Decorator
Призначення
• Зміна поведінки об’єкта без зміни
  інтерфейсу
• Додання функціональності динамічно
• Приклад: Додавання валідації
public interface ISurveysImporter
{
    void Import();
}
public sealed class SurveysImporter :
    ISurveysImporter
{
    ...
    public void Import()
    {
        // ... initialize import here
        fileImporterStrategy.Import();
        // ... report completed successfully
    }
}
public sealed class SecurityCheckingSurveysImporter :
    ISurveysImporter
    {
        private readonly ISurveysImporter importer;

       public void Import()
       {
           if (GetCurrentUserRole() != "Admin")
           {
               throw new InvalidOperationException(
                 "User is not allowed to import surveys.");
           }
           importer.Import();
       }
...
Реалізація
• Декоратор реалізує інтерфейс початкового
  об’єкту
• Декоратор зберігає посилання на
  початковий об’єкт
• Початковий об’єкт не знає про додаткову
  функціональність
• Декоратори можуть поєднуватись
• Композиція замість наслідування
Вже відомі шаблони
• Iterator
   – IEnumerable<T> + IEnumerator<T>
   – yield return -- компілятор сам генерує ітератор
• Observer
   – C# events, based on delegates
• Proxy
   – Доступ до веб-сервісів
• MVC
• Repository

More Related Content

PPTX
Design patterns part 1
PPTX
Advanced c sharp part 3
PPTX
PPTX
.NET Platform. C# Basics
PPTX
PPT
ODP
Phpunit модульне тестування
PPTX
Version control
Design patterns part 1
Advanced c sharp part 3
.NET Platform. C# Basics
Phpunit модульне тестування
Version control

What's hot (7)

PPTX
01 c# basics
PPTX
tsql
PPTX
Windows service
PPTX
SQL: Indexes, Select operator
PPTX
SQL Grouping, Joins
PPTX
10 asp.net
PPTX
Clean code (UA)
01 c# basics
tsql
Windows service
SQL: Indexes, Select operator
SQL Grouping, Joins
10 asp.net
Clean code (UA)
Ad

Viewers also liked (10)

PPT
Oop - TTm
PPTX
#3 Об'єктно орієнтоване програмування (ч. 2)
PPTX
Составные части объектного подхода
PPTX
Service oriented programming
PPTX
PPTX
ASP.Net part 2
PPTX
Mobile applications development
PPTX
принципы ооп и программирование классов в C#
PDF
Python: Модули и пакеты
PDF
Social networking
Oop - TTm
#3 Об'єктно орієнтоване програмування (ч. 2)
Составные части объектного подхода
Service oriented programming
ASP.Net part 2
Mobile applications development
принципы ооп и программирование классов в C#
Python: Модули и пакеты
Social networking
Ad

Similar to Design patterns part 2 (20)

PPTX
[Knowledge Sharing] - Unit Testing by Pavlo Serdyuk (UKR)
PDF
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
PPTX
Automated testing
PPTX
cpp-2013 #20 Best practices
PDF
Загальні принципи розроблення АРМ оператора на базі SCADA/HMI
PPT
Lec12 користувацькi елементи керування ed
PPTX
CoreCamp "Automated testing basics for developers"
PPT
Lec11 користувацькi елементи керування
PPTX
Лекція №12 Передача параметрів у функцію.pptx
PPTX
ASP.Net basics
PDF
[Knowledge Sharing] - Behavioral patterns by Pavlo Serdyuk (UKR)
PPTX
Code driven testing (UA)
PDF
Anton Serputko Start performance-testing-from-scratch, BAQ
PPTX
"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi
PDF
Інші підсистеми
PDF
Lecture 06. iOS Programming. Основи Objective-C
PDF
Igor Dumbur: Інженерна досконалість та DevOps(UA)
PDF
Тестування при розробці програмного забезпечення. Unit Tests.
PDF
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
PDF
Igor Dumbur: Інженерна досконалість та DevOps (UA)
[Knowledge Sharing] - Unit Testing by Pavlo Serdyuk (UKR)
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
Automated testing
cpp-2013 #20 Best practices
Загальні принципи розроблення АРМ оператора на базі SCADA/HMI
Lec12 користувацькi елементи керування ed
CoreCamp "Automated testing basics for developers"
Lec11 користувацькi елементи керування
Лекція №12 Передача параметрів у функцію.pptx
ASP.Net basics
[Knowledge Sharing] - Behavioral patterns by Pavlo Serdyuk (UKR)
Code driven testing (UA)
Anton Serputko Start performance-testing-from-scratch, BAQ
"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi
Інші підсистеми
Lecture 06. iOS Programming. Основи Objective-C
Igor Dumbur: Інженерна досконалість та DevOps(UA)
Тестування при розробці програмного забезпечення. Unit Tests.
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
Igor Dumbur: Інженерна досконалість та DevOps (UA)

More from Victor Matyushevskyy (13)

PPTX
Multithreading and parallelism
PPTX
Java script + extjs
PPTX
Основи Баз даних та MS SQL Server
PPTX
PPTX
Windows forms
PPTX
PPTX
06.1 .Net memory management
PPTX
05 functional programming
PPTX
04 standard class library c#
PPTX
#2 Об'єктно орієнтоване програмування (ч. 1)
PPTX
#1 C# basics
PPTX
#0 Вступна лекція
Multithreading and parallelism
Java script + extjs
Основи Баз даних та MS SQL Server
Windows forms
06.1 .Net memory management
05 functional programming
04 standard class library c#
#2 Об'єктно орієнтоване програмування (ч. 1)
#1 C# basics
#0 Вступна лекція

Design patterns part 2

  • 2. Розглянемо • Presentation pattern Model View Presenter • Шаблони поведінки • Структурні шаблони • Деякі вже відомі нам шаблони
  • 4. Призначення Розділення • Даних для показу • Логіки програми • Відображення даних
  • 5. Сповіщає Presenter displays про дії користувача, відображає дані Дані для показу updates View Model change request Presenter fetches Завантажує дані, передає дані на View, реагує на дії користувача
  • 6. View Model Presenter UI Domain Data Access
  • 7. Відповідальності: Model • Контейнер для даних для відображення • Supervising Controller: View знає про Модель • Passive View: View не знає про Модель • Також може бути класом з предметної області
  • 8. Відповідальності: View • Є формою, показує UI • Створює Презентер, передає себе йому • Перенаправляє дії користувача Презентеру • Може знати про Модель • Або може надавати детальний інтерфейс для встановлення даних • Звертається до конкретного Презентера
  • 9. Відповідальності: Presenter • Реагує на дії користувача • Оновлює View даними з Моделі • Позбавляє View відповідальності за логіку та взаємодію з бізнес-класами та data access – Презентер отримує дані з бізнес-рівня – Трансформація/фільтрування даних – Презентер зберігає зміни, зроблені користувачем • Звертається до View через інтерфейс IView
  • 10. Модифікації • Supervising Controller – View відповідає за data binding Моделі – Презентер передає Модель на View – Презентер керує складнішими взаємодіями • Passive View – Презентер відповідає за передачу кожної частини даних на View – View лише відображає передані прості дані
  • 11. Застосовується • Windows Forms – Існують розвинені MVP фреймворки • ASP.NET Web Forms
  • 13. public sealed class SurveysImporter { public void Import() { // ... initialize import here switch (GetFileStorageType(importContext)) { case SurveysStorageType.Xls: ImportFromExcel(); break; case SurveysStorageType.Csv: ImportFromCsvFile(); break; case ... default: DoNothingButLog(); break; } // ... report import completed successfully }
  • 14. public sealed class SurveysImporterWithStrategy { private readonly IFileImporterStrategy fileImporterStrategy; public void Import() { // ... initialize import here fileImporterStrategy.Import(); // ... report import completed successfully }
  • 15. Призначення • Інкапсуляція алгоритму • Зміна та розвиток алгоритму окремо від клієнта • Винесення наборів різної поведінки з класу • Усунення умовних операторів • Уникнення зміни класу при додаванні нового алгоритму
  • 16. Реалізація • Створення класу-стратегії для кожної варіації алгоритму • Створення спільного інтерфейсу для всіх цих алгоритмів • Стратегія може використовувати клас- клієнт • Або інший контекст
  • 17. public class FilesSender { public void SendToServer(Directory directory, Context context) { if (context.SendTopLevelFilesFirst) { foreach (var file in directory.Files) { SendToServer(file); } foreach (var childDirectory in directory.Directories) { SendToServer(childDirectory, context); } }
  • 18. Higher order functions • Є стратегіями
  • 19. public class FilesSender { private readonly Func<Directory, IEnumerable<File>> enumerateFiles; public FilesSenderWithStrategy( Func<Directory, IEnumerable<File>> directoryTraverser) { enumerateFiles = directoryTraverser; } public void SendToServer(Directory directory, Context context) { foreach (var file in enumerateFiles(directory)) { SendToServer(file); } }
  • 21. public class SurveysImporter { public void Import() { InitializeImport(); DoImport(); NotifyUsers(); ReportSuccessfullCompletion(); }
  • 22. public class CsvSurveysImporter : SurveysImporterWithTemplateMethod { protected override void DoImport() { // CSV import implementation here } protected override void NotifyUsers() { // users notification implementation here } }
  • 23. Призначення • Алгоритм складається з декількох кроків • Реалізація одного кроку може змінюватись • (або декількох кроків) • Інкапсуляція незмінної послідовності кроків • Можливість задати реалізацію кроків, що можуть змінюватись • Зміна кроків алгоритму без зміни його структури
  • 24. Реалізація • Підкласи перевизначають окремі кроки алгоритму, визначеного в базовому класі • Базується на наслідуванні • Альтернатива – Strategy
  • 25. Приклад • ASP.NET page lifecycle – OnInit(), OnLoad() etc.
  • 27. private void Import(Survey survey) { if (survey.CreatedBy == currentUser && survey.CreatedOn < DateTime.Today && ( new[] { SurveyState.New, SurveyState.Finished } .Contains(survey.State) || survey.State == SurveyState.Paused && !survey.HasAnswers ) && !AlreadyExistsSurveyWithTitle(survey.Title)) { // create new or update existing survey } }
  • 28. Призначення • Представлення дії як об’єкта • Відділення виконання дії від деталей і залежностей, необхідних для реалізації дії • Додавання нових дій без зміни клієнтів
  • 29. public interface ICommand { void Execute(); } Не приймає аргументів public interface ICommand<T> { void ExecuteFor(T obj); }
  • 30. public class ImportSurveyCommand : ICommand<Survey> { private readonly string currentUser; private readonly object importContext; public ImportSurveyCommand(string currentUser, object importContext) { this.currentUser = currentUser; this.importContext = importContext; } public void ExecuteFor(Survey obj) { // create new or update existing survey } }
  • 31. private void Import(Survey survey) { if (survey.CreatedBy == currentUser && ...) { var importSurvey = new ImportSurveyCommand( currentUser, GetImportContext()); importSurvey.ExecuteFor(survey); } }
  • 32. Команда може використовуватись для undo функціональності public interface ICommand { bool CanExecute(); void Execute(); void Undo(); }
  • 34. private void Import(Survey survey) { if (survey.CreatedBy == currentUser && survey.CreatedOn < DateTime.Today && ( new[] { SurveyState.New, SurveyState.Finished } .Contains(survey.State) || survey.State == SurveyState.Paused && !survey.HasAnswers ) && !AlreadyExistsSurveyWithTitle(survey.Title)) { // create new or update existing survey } }
  • 35. Передумови • Бізнес-правило містить багато коду • Правило логічно складне • Правило може часто змінюватись • Правил може бути декілька • Призначення: спрощення коду класу-клієнта
  • 36. public interface ISpecification<T> { bool IsSatisfiedBy(T obj); } public class SurveyShouldBeImported : ISpecification<Survey> { public bool IsSatisfiedBy(Survey obj) { // ... } }
  • 37. Реалізація • Інкапсулює булеве бізнес-правило • Можливі композитні Специфікації – AndSpecification, OrSpecification, NotSpecification • Можливе поєднання Команд та Специфікацій
  • 38. public class AndSpecification<T> : ISpecification<T> { private readonly ISpecification<T> first; private readonly ISpecification<T> second; public AndSpecification(ISpecification<T> first, ISpecification<T> second) { this.first = first; this.second = second; } public bool IsSatisfiedBy(T obj) { return first.IsSatisfiedBy(obj) && second.IsSatisfiedBy(obj); } }
  • 40. Призначення • Класи-клієнти використовують певний інтерфейс • Потрібне перетворення інтерфейсу одного класу в інтерфейс іншого • Для використання існуючих класів • Адаптує один інтерфейс до іншого
  • 41. Приклад public interface ISurveyRepository { IList<Survey> GetAll(); Survey Get(int id); }
  • 43. Призначення • Зміна поведінки об’єкта без зміни інтерфейсу • Додання функціональності динамічно • Приклад: Додавання валідації
  • 44. public interface ISurveysImporter { void Import(); } public sealed class SurveysImporter : ISurveysImporter { ... public void Import() { // ... initialize import here fileImporterStrategy.Import(); // ... report completed successfully } }
  • 45. public sealed class SecurityCheckingSurveysImporter : ISurveysImporter { private readonly ISurveysImporter importer; public void Import() { if (GetCurrentUserRole() != "Admin") { throw new InvalidOperationException( "User is not allowed to import surveys."); } importer.Import(); } ...
  • 46. Реалізація • Декоратор реалізує інтерфейс початкового об’єкту • Декоратор зберігає посилання на початковий об’єкт • Початковий об’єкт не знає про додаткову функціональність • Декоратори можуть поєднуватись • Композиція замість наслідування
  • 47. Вже відомі шаблони • Iterator – IEnumerable<T> + IEnumerator<T> – yield return -- компілятор сам генерує ітератор • Observer – C# events, based on delegates • Proxy – Доступ до веб-сервісів • MVC • Repository