sonyps4.ru

Защита от компьютерных атак. Компьютерная атака

Архитектура

Проектирование компьютерных программ

История

Польза

Главная польза каждого отдельного шаблона состоит в том, что он описывает решение целого класса абстрактных проблем. Также тот факт, что каждый шаблон имеет свое имя, облегчает дискуссию об абстрактных структурах данных (ADT) между разработчиками, так как они могут ссылаться на известные шаблоны. Таким образом, за счёт шаблонов производится унификация терминологии, названий модулей и элементов проекта.

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

В отличие от идиом, шаблоны независимы от применяемого языка программирования.

Критика

Иногда шаблоны консервируют громоздкую и малоэффективную систему понятий, разработанную узкой группой. Когда количество шаблонов возрастает, превышая критическую сложность, исполнители начинают игнорировать шаблоны и всю систему, с ними связанную.

Нередко шаблонами заменяется отсутствие или недостаточность документации в сложной программной среде.

Есть мнение, что слепое применение шаблонов из справочника, без осмысления причин и предпосылок выделения каждого отдельного шаблона, замедляет профессиональный рост программиста, так как подменяет творческую работу механическим подставлением шаблонов. Люди, придерживающиеся данного мнения, считают, что знакомиться со списками шаблонов надо тогда, когда «дорос» до них в профессиональном плане - и не раньше. Хороший критерий нужной степени профессионализма - выделение шаблонов самостоятельно, на основании собственного опыта. При этом, разумеется, знакомство с теорией, связанной с шаблонами, полезно на любом уровне профессионализма и направляет развитие программиста в правильную сторону. Сомнению подвергается только использование шаблонов «по справочнику».

Шаблоны могут пропагандировать плохие стили разработки приложений, и зачастую слепо применяются.

Для преодоления этих недостатков используется рефакторинг .

Основные типы шаблонов проектирования

Основные шаблоны (Fundamental)

  • Marker interface
  • Property Container

Порождающие шаблоны проектирования

Структурные шаблоны (Structural)

Поведенческие шаблоны (Behavioral)

Шаблоны параллельного программирования (Concurrency)

  • Active Object
  • Balking
  • Guarded suspension
  • Half-Sync/Half-Async
  • Leaders/followers
  • Monitor Object
  • Reactor
  • Read write lock
  • Scheduler
  • Thread pool
  • Thread-Specific Storage
  • Single Thread Execution

MVC

  • Enterprise

    Unsorted

    • Property Container
    • Event Channel
    • Repository/Хранилище

    Другие типы шаблонов

    Также на сегодняшний день существует ряд других шаблонов:

    См. также

    • Обобщённое программирование
    • Ссылки

      • Ольга Дубина Обзор паттернов проектирования . - Обзор нескольких наиболее значительных монографий, посвященных паттернам проектирования информационных систем. Проверено 5 сентября 2006.
      • Portland Pattern Repository - список шаблонов проектирования на движке вики
      • mgrand’s book - сайт с описанием большого количества шаблонов проектирования
      • Resign Patterns - проломы проектно-дизориентированного проектирования (пародия на паттерны)
      • Eclipse’s Culture of Shipping (англ.) Erich Gamma

      Литература

      • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. - СПб: «Питер» , 2007. - С. 366. - ISBN 978-5-469-01136-1 (также ISBN 5-272-00355-1)
      • Крэг Ларман Применение UML 2.0 и шаблонов проектирования = Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development. - М.: «Вильямс» , 2006. - С. 736. - ISBN 0-13-148906-2
      • Мартин Фаулер Архитектура корпоративных программных приложений = Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series). - М.: «Вильямс» , 2007. - С. 544. - ISBN 0-321-12742-0
      • Джошуа Кериевски Рефакторинг с использованием шаблонов (паттернов проектирования) = Refactoring to Patterns (Addison-Wesley Signature Series). - М.: «Вильямс» , 2006. - С. 400. - ISBN 0-321-21335-1
      • Скотт В. Эмблер, Прамодкумар Дж. Садаладж Рефакторинг баз данных: эволюционное проектирование = Refactoring Databases: Evolutionary Database Design (Addison-Wesley Signature Series). - М.: «Вильямс» , 2007. - С. 368. - ISBN 0-321-29353-3

      Wikimedia Foundation . 2010 .

  • Паттерсон, Джемс
  • Паттерсон, Персиваль

Смотреть что такое "Паттерны проектирования" в других словарях:

    Шаблон проектирования - У этого термина существуют и другие значения, см. Паттерн. В разработке программного обеспечения, шаблон проектирования или паттерн (англ. design pattern) повторимая архитектурная конструкция, представляющая собой решение проблемы… … Википедия

    Шаблоны проектирования - (паттерн, англ. design pattern) это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения. Паттерн не является законченным… … Википедия

    Шаблоны проектирования GRASP - GRASP (англ. General Responsibility Assignment Software Patterns (общие образцы распределения обязанностей)) паттерны, используемые в объектно ориентированном проектировании для решения общих задач по назначению обязанностей классам и объектам. В … Википедия

Если вы когда-либо интересовались, что представляют собой шаблоны проектирования, то добро пожаловать. В этой статье я расскажу, что это такое, зачем они нужны, как их использовать, и приведу примеры наиболее распространенных шаблонов на PHP.

Что такое шаблоны проектирования?

Шаблоны проектирования - это проверенные и готовые к использованию решения часто возникающих в повседневном программировании задач. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее. Шаблон проектирования, подходящий под задачу, реализуется в каждом конкретном случае. Кроме того, он не зависит от языка программирования. Хороший шаблон легко реализуется в большинстве, если не во всех языках, в зависимости от выразительных средств языка. Следует, однако, помнить, что такой шаблон, будучи примененным неправильно или к неподходящей задаче, может принести немало проблем. Тем не менее, правильно примененный шаблон поможет решить задачу легко и просто.

Существует три типа шаблонов:

  • структурные;
  • порождающие;
  • поведенческие.

Структурные шаблоны определяют отношения между классами и объектами, позволяя им работать совместно.

Порождающие шаблоны предоставляют механизмы инициализации, позволяя создавать объекты удобным способом.

Поведенческие шаблоны используются для того, чтобы упростить взаимодействие между сущностями.

Зачем нужны шаблоны проектирования?

Шаблон проектирования, по своей сути, это продуманное решение той или иной задачи. Если вы столкнулись с известной задачей, почему бы не использовать готовое решение, проверенное опытом?

Пример

Давайте представим, что вам необходимо объединить два класса, которые выполняют различные операции в зависимости от ситуации. Эти классы интенсивно используются существующей системой, что не позволяет удалить один из них и добавить его функциональность во второй. Кроме того, изменение кода потребует его тщательного тестирования, поскольку такой рефакторинг ведет к неизбежным ошибкам. Вместо этого вы можете реализовать шаблоны «Стратегия» и «Адаптер» и с их помощью решить задачу.

Class StrategyAndAdapterExampleClass { private $_class_one; private $_class_two; private $_context; public function __construct($context) { $this->_context = $context; } public function operation1() { if($this->_context == "context_for_class_one") { $this->_class_one->operation1_in_class_one_context(); } else ($this->_context == "context_for_class_two") { $this->_class_two->operation1_in_class_two_context(); } } }

Просто, не правда ли? Давайте посмотрим поближе на шаблон «Стратегия».

Шаблон «Стратегия»

Стратегия - поведенческий шаблон, который позволяет выбрать поведение программы в процессе выполнения в зависимости от контекста путем инкапсуляции нескольких алгоритмов в разных классах.

В примере выше выбор стратегии основан на значении переменной $context , которое было в момент создания объекта. Если значение было "context_for_class_one" , программа будет использовать класс class_one . И наоборот.

Хорошо, но где это можно использовать?

Представьте, что вы разрабатываете класс, который может создать или обновить запись в базе данных. В обоих случаях входные параметры будут одни и те же (имя, адрес, номер телефона и т. п.), но, в зависимости от ситуации, он будет должен использовать различные функции для обновления и создания записи. Можно каждый раз переписывать условие if/else , а можно создать один метод, который будет принимать контекст:

Class User { public function CreateOrUpdate($name, $address, $mobile, $userid = null) { if(is_null($userid)) { // пользователя не существует, создаем запись } else { // запись есть, обновляем ее } } }

Обычно шаблон «Стратегия» подразумевает инкапсуляцию алгоритмов в классы, но в данном случае это излишне. Помните, что вы не обязаны следовать шаблону слово в слово. Любые варианты допустимы, если они решают задачу и соответствуют концепции.

Шаблон «Адаптер»

Адаптер - структурный шаблон, который позволяет использовать класс, реализующий нужные функции, но имеющий неподходящий интерфейс.

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

Как его использовать?

Другое название адаптера - «Обертка». Он «оборачивает» новый интерфейс вокруг класса для его использования. Классический пример: вам надо создать класс предметной модели, имея классы объектов в базе данных. Вместо того, чтобы обращаться к табличным классам напрямую и вызывать их методы по одному, вы можете инкапсулировать вызовы этих методов в одном методе в адаптере. Это не только позволит повторно использовать набор операций, но и избавит вас от постоянного переписывания большого количества кода, если вам потребуется выполнить тот же набор действий в другом месте.

Сравните два примера.

Без адаптера
$user = new User(); $user->CreateOrUpdate(// параметры); $profile = new Profile(); $profile->CreateOrUpdate(// параметры);

Если нам придется использовать такой код повторно, мы будем вынуждены переписывать все это заново.

С использованием адаптера

Мы можем создать класс-обертку Account:

Class Account() { public function NewAccount(// параметры) { $user = new User(); $user->CreateOrUpdate(// часть параметров); $profile = new Profile(); $profile->CreateOrUpdate(// часть параметров); } } $account_domain = new Account(); $account_domain->NewAccount(// параметры);

Теперь мы можем использовать класс Account каждый раз и, кроме того, мы можем добавить в него дополнительные функции.

Шаблон «Метод-фабрика»

Фабрика - порождающий шаблон, который представляет собой класс с методом для создания различных объектов.

Основная цель этого шаблона - инкапсулировать процедуру создания различных классов в одной функции, которая в зависимости от переданного ей контекста возвращает необходимый объект.

Как его использовать?

Фабрика обычно используется для создания различных вариантов базового класса. Допустим, у вас есть класс кнопки - Button - и три варианта - ImageButton , InputButton и FlashButton . С помощью фабрики вы можете создавать различные варианты кнопок в зависимости от ситуации.

Сначала создадим три класса:

Abstract class Button { protected $_html; public function getHtml() { return $this->_html; } } class ImageButton extends Button { protected $_html = "..."; // HTML-код кнопки-картинки } class InputButton extends Button { protected $_html = "..."; // HTML-код обычной кнопки (); } class FlashButton extends Button { protected $_html = "..."; // HTML-код Flash-кнопки }

Теперь мы можем написать нашу фабрику:

Class ButtonFactory { public static function createButton($type) { $baseClass = "Button"; $targetClass = ucfirst($type).$baseClass; if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass)) { return new $targetClass; } else { throw new Exception("The button type "$type" is not recognized."); } } }

и использовать ее:

$buttons = array("image","input","flash"); foreach($buttons as $b) { echo ButtonFactory::createButton($b)->getHtml() }

На выходе должен получиться HTML со всеми типами кнопок. Таким образом мы получили возможность указать, кнопку какого типа мы хотим получить, и использовать код повторно.

Шаблон «Декоратор»

Декоратор - это структурный шаблон, который позволяет добавить новое поведение объекту в процессе выполнения программы в зависимости от ситуации.

Цель - в расширении поведения конкретного объекта без необходимости изменять поведение базового класса. Это позволит использовать несколько декораторов одновременно. Этот шаблон - альтернатива наследованию. В отличие от наследования, декоратор добавляет поведение в процессе выполнения программы.

Для реализации декоратора нам понадобится:

  1. Унаследовать класс-декоратор от базового.
  2. Добавить поле со ссылкой на базовый класс в декоратор.
  3. Передать ссылку на декорируемый объект в конструктор декоратора.
  4. Перенаправить методы из декоратора на декорируемый объект.
  5. Переопределить методы в декораторе, поведение которых необходимо изменить.

Как его использовать?

Предположим, что у нас есть объект, который должен иметь определенное поведение в определенной ситуации. Например, у нас есть HTML-ссылка для выхода из аккаунта, которая должна по-разному показываться в зависимости от того, на какой странице мы находимся. Это тот самый случай, когда нам помогут декораторы.

Сначала определимся, какие «декорации» нам нужны:

  • Если мы на заглавной странице и вошли в аккаунт, ссылка должна быть в h2 -теге.
  • Если мы на любой другой странице и вошли в аккаунт, ссылка должна быть подчеркнутой.
  • Если мы вошли в аккаунт, ссылка должна быть в strong -теге.

Теперь мы можем написать сами декораторы:

Class HtmlLinks { // методы для работы с любой HTML-ссылкой } class LogoutLink extends HtmlLinks { protected $_html; public function __construct() { $this->_html = "Logout"; } public function setHtml($html) { $this->_html = $html; } public function render() { echo $this->_html; } } class LogoutLinkH2Decorator extends HtmlLinks { protected $_logout_link; public function __construct($logout_link) { $this->_logout_link = $logout_link; $this->setHtml("" . $this->_html . ""); } public function __call($name, $args) { $this->_logout_link->$name($args); } } class LogoutLinkUnderlineDecorator extends HtmlLinks { protected $_logout_link; public function __construct($logout_link) { $this->_logout_link = $logout_link; $this->setHtml("" . $this->_html . ""); } public function __call($name, $args) { $this->_logout_link->$name($args); } } class LogoutLinkStrongDecorator extends HtmlLinks { protected $_logout_link; public function __construct($logout_link) { $this->_logout_link = $logout_link; $this->setHtml("" . $this->_html . ""); } public function __call($name, $args) { $this->_logout_link->$name($args); } }

Теперь мы можем использовать их так:

$logout_link = new LogoutLink(); if($is_logged_in) { $logout_link = new LogoutLinkStrongDecorator($logout_link); } if($in_home_page) { $logout_link = new LogoutLinkH2Decorator($logout_link); } else { $logout_link = new LogoutLinkUnderlineDecorator($logout_link); } $logout_link->render();

Обратите внимание, как можно использовать несколько декораторов на одном объекте. Все они используют функцию __call для вызова оригинального метода. Если мы войдем в аккаунт и перейдем на заглавную страницу, результат будет такой:

Logout

Шаблон «Одиночка»

Одиночка - порождающий шаблон, который позволяет убедиться, что в процессе выполнения программы создается только один экземпляр класса с глобальным доступом.

Его можно использовать как точку «координации» для других объектов, поскольку поля «Одиночки» будут одинаковы для всех, кто его вызывает.

Как его использовать?

Если вам необходимо передавать определенный экземпляр из класса в класс, вы можете передавать его каждый раз через конструктор или использовать «Одиночку». Допустим, у вас есть класс Session , который содержит данные о текущей сессии. Поскольку сессия инициализируется только один раз, мы можем реализовать его так:

Class Session { private static $instance; public static function getInstance() { if(is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } private function __construct() { } private function __clone() { } // прочие методы сессии... ... ... } // get a session instance $session = Session::getInstance();

Теперь мы можем получить доступ к сессии из различных участков кода, даже из других классов. Метод getInstance всегда будет возвращать одну и ту же сессию.

Заключение

В этой статье мы рассмотрели только наиболее часто встречающиеся шаблоны из множества. Если вы хотите узнать больше о шаблонах проектирования, вы найдете достаточно информации на Википедии . Для более полной информации обратите внимание на знаменитую книгу «Приемы объектно-ориентированного проектирования» «Банды четырех».

И последнее: при использовании того или иного шаблона убедитесь, что вы решаете задачу правильным способом. Как уже упоминалось, при неправильном использовании шаблоны проектирования могут доставить больше проблем, чем решить. Но при правильном - их пользу нельзя переоценить.

Современное программирование практически невозможно без применения специальных шаблонов проектирования (паттернов). Паттерны представляют собой специальные способы построения и организации программного продукта, которое позволяет решить наиболее «популярные» сложности и ошибки в программировании. Обобщая данный термин, можно сказать, что паттерны представляют собой своеобразный свод правил, который позволяет избавить программиста от общих, формализованных проблем.
Все известные на сегодняшний день паттерны проектирования можно разделить на несколько подвидов, это: порождающие шаблоны, паттерны поведения, структурные и, так называемые, принципы SOLID.
К порождающим паттернам относятся следующие: Абстрактная фабрика, Builder, Factory Method, Singleton, Prototype. Они называются порождающими в связи с тем, что подобные паттерны абстрагируют процесс создания экземпляров классов и объектов.
К поведенческим паттернам относятся: Interpreter, Iterator, Mediator, Template Method, State, Strategy, Visitor. Они называются поведенческими потому что определяют процессы взаимодействия между классами и объектами, соответственно, определяют поведение.
Структурные паттерны включают в себя: Proxy, Facade, Composite, Bridge, Adapter. Такие паттерны в разработке программного обеспечения, в коммерческих целях, встречаются довольно редко, поэтому и их описание найти немного проблематично. По сравнению с перечисленными выше паттернами, эти используются не часто, только в определенных, исключительных случаях. Подобные шаблоны рассматривают классы и объекты, используемые в программе, как структуры, соответственно, более сложные.
Применение подобных паттернов позволяет улучшить понимание кода, например, если вы работаете не один, а в команде, а также упростить процедуру внедрения новых участков кода или изменения старых, без необходимости в написании избыточного кода.
Принципы Solid, по своей сути представляют один большой шаблон проектирования, который включает в себя несколько маленьких паттернов. SOLID, как можно догадаться, является акронимом и означает следующее: S – принцип единственной обязанности, O - открытости и закрытости, L - подстановки Лисков, I - разделения интерфейсов в программу, и D -инверсии зависимостей. В отличии от представленных выше паттернов, подобные принципы нельзя назвать какими-то шаблонами решения формализованных проблем. Эти принципы позволяют создать грамотное, структурированное программное решение, которое упрощает изменение определенных участков кода и даже его изменение.
Таким образом, подытоживая все описанное выше, можно сказать, что программирование без применения принципов SOLID или паттернов, буквально невозможно. Скорее всего, работать без них можно только если вы создаете какое-то небольшое приложения, над которым в дальнейшем будете также работать только вы один и точно знаете – какой участок кода за что отвечает. Если вы работаете в команде, то без применения шаблонов и принципов – вам далеко не уйти. Так будет проще разбираться в коде вашим товарищам и сама работа станет легче.


Загрузка...