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

What's hot (7)

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

Viewers also liked (10)

PPT
Oop - TTm
Vitaliy Galushka
 
PPTX
#3 Об'єктно орієнтоване програмування (ч. 2)
Victor Matyushevskyy
 
PPTX
Составные части объектного подхода
Ural Federal University named after First President of Russia B.N. Yeltsin
 
PPTX
Service oriented programming
Victor Matyushevskyy
 
PPTX
ASP.Net MVC
Victor Matyushevskyy
 
PPTX
ASP.Net part 2
Victor Matyushevskyy
 
PPTX
Mobile applications development
Victor Matyushevskyy
 
PPTX
принципы ооп и программирование классов в C#
bolevik
 
PDF
Python: Модули и пакеты
Theoretical mechanics department
 
PDF
Social networking
vishnukdixit
 
Oop - TTm
Vitaliy Galushka
 
#3 Об'єктно орієнтоване програмування (ч. 2)
Victor Matyushevskyy
 
Составные части объектного подхода
Ural Federal University named after First President of Russia B.N. Yeltsin
 
Service oriented programming
Victor Matyushevskyy
 
ASP.Net part 2
Victor Matyushevskyy
 
Mobile applications development
Victor Matyushevskyy
 
принципы ооп и программирование классов в C#
bolevik
 
Python: Модули и пакеты
Theoretical mechanics department
 
Social networking
vishnukdixit
 
Ad

Similar to Design patterns part 2 (20)

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

More from Victor Matyushevskyy (13)

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

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