Паттерны проектирования для человеков.

    Была задача в максимально короткие сроки (зачет нужно было сдавать) человеку далекому от программирования объяснить паттерны на самом простом уровне.
    В результате баланса простоты изъяснения и адекватности, образовалась эта шпаргалка.
    Просьба оценить эту самую адекватность и простоту.

    Ликбез:
    Инкапсуляция — сокрытие сущности объекта за интерфейсом (нам пох как у нас хранится картинка, нам нада только уметь выводить еще на экран, ресайзить, поворачивать...)
    Экземпляр класса — объект :)

    Краткое введение:
    Паттерны делятся на 3 основные группы:
    1. Порождающие — паттерны отвечающие за создание объектов;
    2. Структурные — определяют структуру представления классов/объектов;
    3. Паттерны поведения — паттерны для инкапсуляции (сокрытия) действий над объектами.

    1. Порождающие


    Abstract Factory — создает объекты похожих классов.
    У нас есть абстрактный класс и наследники, создается абстрактная фабрика и конкретные фабрики для наследников. Необходим для того что бы отделить методику создания объектов разных классов. Классы должны быть связаны.
    Пример на C#
    На русском с рисунками

    Builder — отделяет создание объекта и его представления.
    Позволяет при вызове одного и того же метода создания, получить разные результаты.
    Пример на C#
    На русском с рисунками

    Singleton — гарантирует наличие одного экземпляра класса.
    Используется, если в системе нужно гарантировать наличие одного экземпляра класса (объекта). Например, в системе может быть только один бланк учета черной бухгалтерии. Это аналог глобальной переменной, но намного круче.
    Пример на C#
    На русском с рисунками

    2. Структурные


    Adapter — адаптирует :) интерфейс одного класса к другому.
    Допустим есть два класса, и мы имеем доступ только к интерфейсам (код менять низя). И нужно наладить взаимодействие. Тогда применяется паттерн. Он берет интерфейс класса А и его методы преобразовывает для класса В.
    Пример: есть класс для работы с комплексными числами, у него методы ToCompl(int i) и есть другой класс который знает про комплексные числа но думает что там метод называется ConvertToComplex(int i), делаем адаптер для первого класса, который будет иметь метод ConvertToComplex, а в нем вызывать ToCompl (пример тупой, оперирует только названиями, а в реале там можно заменять все, например вызывать не 1 метод, а 15)
    Пример на C#
    На русском с рисунками

    Composite — позволяет создать один простой интерфейс для кучи похожих классов.
    Допустим есть разные геометрические фигуры(Line, Circle), наследуем их от класса Figure у которого есть метод Draw и тем самым мы обеспечим простой вызов прорисовки для всех наследников.
    Пример на C#
    На русском с рисунками


    Decorator Динамическое добавление функционала для класса.
    Например есть класс фотка, и нам нада навесить рамку, делаем класс который будет выводит фотку (метод класса Фотка) и потом выводить рамку (уже своими методами)
    Пример на C#
    На русском с рисунками

    Proxy — заменяет класс на себя :)
    Получается что для всей системы прокси выглядит как необходимый класс, но не является таковым.
    Например есть большой объект (пдф документ) и нам нада его отобразить на экране. Грузить весь нельзя (в память не влезет). Поэтому делаем прокси который будет постранично грузить и выводить, но выглядеть он будет как настоящий документ.
    Пример на C#
    На русском с рисунками

    3. Паттерны поведения


    Command — инкапсулирует действие в объект.
    Например есть менюха которая должна выводить сообщение. Мы не просто в обработчике меню пишем вывод, а делаем класс который это делает. Дерево таких классов позволяет организовать такую штуку как «Отменить/пофторить», фактически мы можем сохранять наши действия.
    Пример на C#
    На русском с рисунками

    Iterator — позволяет обходить коллекцию объектов. Например есть вектор (массив) и мы вместо [] пишем методы Next, Previos. Таким образом мы не привязались к массив и в дальнейшем можем заменить его на другую структуру.
    Пример на C#
    На немецком с рисунками

    Memento — позволяет сохранить состояние объекта. Например в фотошопе у нас есть отмена команд, мы применили ацкий фильтр который всю фотку испоганил, обратной ф-ции этого фльтра нет (паттерн Команда не проканает), мы перед применением фильтра, тупо сохраняем фотку и потом можем ее восстановить.
    Пример на C#
    На украинсокм с рисунками

    Observer — налаживает взаимодействие объектов. Например есть формочка, мы нажимаем кнопочку и в текстовом поле выводится «42», можно написать тупо в обработчике кнопки типа изменить поле, но это не тру. Тру: создаем объект Наблюдатель(обычно это сингелтон) и в кнопочке вызываем метод в этом Наблюдателе, а он уже предеает это сообщение всем текстовым полям (их же может стать больше :)
    Пример на C#
    На русском с рисунками

    Mediator — тоже самое что и Observer, но там отношение «Много к многим».
    Например у нас не только кнопочка, а еще и менюшка есть.
    Пример на C#
    На украинсокм с рисунками

    State — позволяет подменять класс его наследниками.
    Например, есть заявка, она или обработана или необработана (третьего не дано). Мы для этих двух состояний делаем классы и наследуем от абстрактного класса СостояниеЗаявки, у которого есть метод ИзменитьСостояние. В реализации этого метода мы будем заменять текущее состояние на нужный нам объект (Обработано, Необработано) эти состояния обычно сингилтоны.
    Пример на C#
    На украинсокм с рисунками

    Strategy — позволяет инкапсулировать алгоритмы.
    Например нам нужно сортировать массив и нам пофигу каким методом (пузырьком, быстрая...) поэтому создаем класс, а от него наследников — конкретные алгоритмы, и уже там — методы Отсортировать, а у же в методах конкретных сортировок реализуем их. Это позволяет что бы другие классы вобще не знали как и что мы сортируем.
    Пример на C#
    На русском с рисунками

    Visitor — позволяет навесить функционал на уже готовый класс.
    Например, есть работник, у него есть черная и белая зарплата. Считается по разному. Класс работника менять низя. Делаем посетителя, у которого будет два метода ПосчитатьРеально и ПосчитатьДляНалоговиков. Он будет брать объект Работник, вытаскивать из него ставку и по разному считать.
    Пример на C#
    На итальянском с рисунками

    upd: Технический редактор — Антон.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 23

      +1
      если бы еще было написано на русском языке без слов-паразитов и идиом…
        +1
        Для хорошего программиста, анг. не сильно мешает!
          +2
          Не мешает, поэтому я с удольствием почитаю SourceMaking вместо этого опуса.
            0
            Спасибо за ссылку, в меморайз!
            +1
            я не про англ, я про стилистику русского языка, Вы уж простите, но «пох, навесить, менюха, тупо» и подобные словечки режут ухо в тексте подобного хорошего содержания
              +2
              Согласен! Просто изначально никто не собирался это показывать общественности. А потом возник спор по поводу вобще адекватности материала.
          +4
          1. В целом неплохо, но IMHO явно не для «далекого от программирования» человека.
          2. Не все стандартные паттерны (под ними понимаю паттерны, описанные в книге GoF) описаны.
          3. С Composite по-моему оказия вышла. Смысл этого паттерна в том, что он позволяет объединять объекты в иерархию. Т.е. создается производный класс, который может хранить в себе несколько объектов того же типа. По ссылке, что Вы дали, это явно видно на UML-диаграмме в виде отношения агрегации «один ко многим» между производным классом и базовым соответственно…

          Итог: можно использовать самому, чтобы повторить паттерны, но научить по этой «шпаргалке» другого без дополнительных устных разъяснений будет крайне затруднительно.
            +1
            Полностью согласен.
            На своем опыте скажу, что объяснить человеку, далекому от программирования, принципы ООП — достаточно сложно, и уж тем более по этой шпаргалке. А без ООП в паттернах никуда ;)
            +1
            Довольно удобно иметь такое краткое описание. Но, чтобы понять суть, философию, почему нужно делать именно так — для этого нужно приводить реальный пример применения, на нем будет очевидна логичность и удобство паттернов. Мне в подобном случае помогло изучение архитектуры .NET, а конкретно — WPF. Подробное изучение примеров помогает настроить мозг на правильный ход мыслей.
              +2
              Молодец! Полезная инфа. Все правильно, только «незачОт» за Composite.

              позволяет создать один простой интерфейс для кучи похожих классов.

              Позволить или запретить создавать интерфейс для кучи похожих классов не запретишь, это решает разработчик. Причем тут паттерн?

              А Composite служит для того, чтобы объединять в одно единое целое объекты со схожим функционалом, и для выполнения какой-либо единой по сути операции (или операций), применимой сразу ко всем объектам в пучке. Скорее как-то так.

                0
                Я бы сказал, что Composite служит для объединения объектов одного типа (вернее, объектов, имеющий один и тот же базовый класс — юзаем полиморфизм :)) с сохранением интерфейса этого самого базового класса.
                +2
                Спасибо за замечание по поводу Копозита! Действительно, такого нагородил. Вычеркну пока, а то своими словами не могу сейчас сформулировать.
                  +2
                  Мне кажется в начале не хватает определения: что такое паттерн. Для тех, кто не знает английский это страшное непонятное слово.
                    +2
                    Интернациональные у вас примеры :)
                      +3
                      Честно сказать, это не для далёкого от программирования человека. Моя мама этого не поняла :). И кстати, чем ваше изложения отличается от книжного. По мне, то тоже самое, только на русском. Примеры должны быть более жизненные.

                      Например, когде мне необходимо было объяснить IoC (Inversion of control), то я пытался обяснить на очень простых вещах. Например так.

                      Есть мальчик Вася, который умеет очищать пол в квартире. Вася может это сделать пылесосом, метлой, щеткой. Для того, чтобы Вася не заморачивался с выбором средства для убирания, есть мама, которая вручает, в зависимости от обстоятельств (чуть-чуть грязно; сильно грязно; чтобы без дела не сидел :) ) Васе необходимый инструмент. Т.к. образом выбор инструмента ложиться на маму, а Вася просто тупо убирает.
                        0
                        Ну ваше изложение это просто вершина педагогики (тут без сарказма)! Мне просто было тяжело придумать нормальные примеры в сжатые сроки, тем не мение, я попытался отойти от книжного изложения, возможно, не всюду это получилось.
                          +2
                          [oftop]
                          Дело в том, что я перподаю олимпиадное да и не только программирование детям. Делаю это не за деньги а для души. Вот и есть некоторый опыт. Таким примерам я научился от своего учителя по математике Шимбарецкого Владимира Николаевича. Он некоторые вещи, которые мы проходили в 8! классе объяснял на яблоках. Ведь так понятнее. Яблоки все любят :)
                            0
                            Может быть напишете статью на эту тему с примерами? Рассказали бы как придумывать понятные жизненные аналоги
                              0
                              Хорошая идея. Я бы тоже с удовольствием в этом поучаствовал (:
                          +3
                          Я тоже заметил, что большинство тонкостей ООП можно легко и доступно объяснить на примере слегка туповатых людей в роли объектов.
                          +1
                          Сдавая недавно курсовую работу, обнаружил, что преподаватели не понимают ООП. А как дело дошло до паттернов проектирования — так плакать захотелось.

                          Первоначально пытался объяснить вкратце, также как и Вы — теорию. К сожалению не получилось.
                          Тогда пришлось на примерах, подобных примеру krolser рассказывать:
                          1. Для чего вообще нужны паттерны (на примере кофе :)
                          2. Каков смысл в их использовании (на том же примере)
                          3. Как создать конкретную реализацию в коде, зная паттерн

                          Так что имхо важно правильно начать. А то, пока на пальцах не объяснишь, некоторые программисты с пятнадцатилетним (а то и более) стажем считают, что:
                          — паттерн проектирования — это код, который скачали с интернета (с)
                          — паттерн проектирования — это когда нажал на кнопку, и нечто проверит вашу программу на правильность
                          — LSP, SRP, OCP — это бред и набор страшных букв

                          Это я к тому, что у Вас не сказано, что такое паттерн. Хотя бы напишите, что это свод здравых советов к тому, как проектировать приложения. Или нечто иное, что хорошо охарактеризовало бы паттерны…
                            +1
                            К сожалению, для меня LSP, SRP, OCP — это набор страшных букв :(
                              0
                              > 1. Для чего вообще нужны паттерны (на примере кофе :)
                              > 2. Каков смысл в их использовании (на том же примере)
                              > 3. Как создать конкретную реализацию в коде, зная паттерн

                              А можете привести объяснение? Просто интересно как на кофе объяснили :)

                            Only users with full accounts can post comments. Log in, please.