html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Принципы GRASP


Про знаменитые принципы SOLID мы уже писали, кроме того я планирую к ним ещё раз вернуться. А вот про принципы GRASP написано по-русски пока не много, а многое из того что написано — отравляет понимание своей заумностью. Конечно, этот вопрос не из самых простых, но и сложность здесь тоже отнюдь не космическая.

Итак, первый и исходный пункт — что это и зачем вообще нужны эти принципы?

Самый главный вопрос — что такое Объектно-ориентированное программирование (ООП)?

В максимально общем виде я бы ответил так: это набор основных концепций (абстракция, инкапсуляция, наследование, полиморфизм), конструкций (классы, методы) и принципов использования всего этого вместе. Концепции — это уже готовые и качественные кирпичики, из которых строится данная стандартная модель; конструкции — те инструменты, с помощью чего это делается, а вот принципы — это некие проверенные временем правила, которые при этом следует соблюдать.


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

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

Разные принципы для одинаковых моделей

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

Да, моделировать — не сложно. Только проблема в том, что мы все-таки имеем дело всего лишь с моделью. А когда объекты (сущности) уже созданы, тогда вступает в игру именно их программирование и проектирование. Объекты должны взаимодействовать, и при этом модель должна быть гибкой, однородной и простой. Вот тут нам и помогают универсальные принципы, которые, повторюсь, во многом близки по смыслу шаблонам.

Итак, GRASP — это набор таких вот принципов по версии такого известного эксперта как Крэг Ларман, который подробно описал их в своей книге — Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development.

GRASP patterns патерны принципы ООП объектно-ориентированное SOLID GRASP-патерны шаблоны

Кстати, она доступна и в переводе на русский. Эта книга, как и книга GoF(Gang of four) — уже заняла свое место в истории, и соответственно принципы GRASP, которым посвящена малая часть книги — безусловно тоже.

Возможно, они не так популярны, как скажем принципы SOLID, скорее всего потому, что они определенны более обобщенными. Эти принципы более абстрактны, чем шаблоны GoF или SOLID

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

General Responsibility Assignment Software Patterns (GRASP ) — это можно перевести так — паттерны распределения ответственности. Суть в том, что это не строгие паттерны как у GoF, это скорее тот смысл, которым мы наделяем объекты. Так что принципы распределения общей ответственности подходят больше чем паттерны. И поэтому название статьи не шаблоны GRASP как было бы идеологически верно, а все-таки принципы GRASP. Суммируя, GRASP — это хорошо документированные, стандартизированные и проверенные временем принципы объектно-ориентированного анализа, а не попытка привнести в ООП что-то принципиально новое

GRASP выделяет следующие 9 принципов-шаблонов:

  • Information Expert (Информационные эксперт) ;
  • Creator (Создатель) ;
  • Controller (Контроллер) ;
  • Low Coupling (Слабая связанность) ;
  • High Cohesion (Высокая сцепленность) ;
  • Pure Fabrication (Чистая выдумка или чистое синтезирование) ;
  • Indirection (Посредник) ;
  • Protected Variations (Сокрытие реализации или защищенные изменения) ;
  • Polymorphism (Полиморфизм).

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

Information Expert

Информационный эксперт или просто эксперт — это скорее ответственность. Экспертом может быть любой класс. Тут даже дело не в проектировании, а в осведомленности. Зачем нам нужен информационный эксперт? Затем, что если объект владеет всей нужной информацией полностью для какой-то операции или функционала, то значит, что этот объект будет выполнять всё сам, либо получать делегировать выполнение этой операции от других.

Итак, рассмотрим пример. Есть некая система продаж. И есть класс Sale (продажа). Нам необходимо посчитать общую сумму продаж. Тогда кто будет считать общую сумму по продажам? Конечно же, класс — Sales , потому что именно он обладает всей информацией необходимой для этого.

Creator

Creator или Создатель — суть ответственности такого объекта в том, что он создает другие объекты. Сразу напрашивается аналогия с фабриками. Так оно и есть. Фабрики тоже имеют именно ответственность — Создатель.

Но есть ряд моментов, которые должны выполняться, когда мы наделяем объект ответственностью создатель:

  1. Создатель содержит или агрегирует создаваемые объекты;
  2. Создатель использует создаваемые объекты ;
  3. Создатель знает, как проинициализировать создаваемый объект ;
  4. Создатель записывает создаваемые объекты (эту штуку я до конце не понял на самом деле).

Controller

Уже где-то слышали, не правда ли? Controller или Контролер — это объект-прослойка между UI-логикой и предметной (бизнес) логикой приложения. Создаем контроллер так, чтобы все вызовы от UI перенаправлялись именно ему и соответственно, все данные UI тоже получает только через него.

Напоминает известные MVC и MVP? Так и есть. Это по сути Presenter из MVP и контроллер из MVC. Разница между MVC и MVP есть, но это касается только направлений вызовов, ну и это тема естественно отдельной большой беседы.

Контроллер отвечает на такой вопрос: «Как UI должен взаимодействовать с доменной логикой приложения?»

Или ещё проще: «Как взаимодействовать с системой?». Это чем-то напоминает фасад дома. Фасад тоже предоставляет облегченный доступ к целой подсистеме объектов. Так и тут: контроллер для UI своего рода фасад, который предоставляет доступ к целой подсистеме бизнес-логики.

GRASP patterns патерны принципы ООП объектно-ориентированное SOLID GRASP-патерны шаблоны

Low Coupling

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

Например, если наш класс Sale реализует интерфейс ISale и другие объекты зависят именно от ISale , т.е. от абстракции, то когда мы захотим внести изменения касательно Sale  — нам нужно будет всего лишь подменить реализацию.

Low Coupling встречается и в SOLID-принципах в виде — Dependency Injection. Да, сейчас чаще можно услышать именно про этот принцип. Но суть здесь остается прежней:

«Программируйте на основе абстракций (интерфейс, абстрактный класс и т.п.), а не реализаций»

High Cohesion

High Cohesion или высокая сцепленность — этот принцип тесно соотносится с слабой связанностью, и они идут в паре, когда одно всегда приводит к другому. Это как инь и янь, — оба всегда вместе. Дело в том, что наши классы когда мы их задумываем, имеют какую-то одну ответственность (Single resposibility principle), например класс Sale (продажа) обладает всеми ответственностями которые касаются продаж, например, как мы уже говорили выше - вычисление общей суммы — Total .

Но давайте представим, что мы совершили оплошность и привнесли в Sale еще такую ответственность, как Payment (платеж). Что получится? Получится, что одни члены класса, которые касаются Sale , буду между собой достаточно тесно связанны, и также члены класса которые оперируют с Payment между собой - будут также тесно связаны, но в целом сцепленность класса SaleAndPayment будет низкой, так как, по сути, мы имеем дело с двумя обособленными частями в одном целом. И резонно будет провести рефакторинг и разделить класс SaleAndPayment на Sale и Payment , которые внутри будут тесно связанны или по другому сцеплены.

Так что высокая сцепленность — это как мера того, что мы не нарушаем single resposibility principle. Вернее сказать, высокая сцепленность получается в результате соблюдения такого приципа из SOLID, как single resposibility principle (SRP).

Основной вопрос на который дает ответ высокая сцепленность — «Как поддерживать объекты сфокусированными на одной ответственности, понятными, управляемыми и как побочный эффект иметь слабо связанный код?»

Их нужно разделять. Подробнее это описано в 17 главе вышеупомянутой книги Лармана.

Pure Fabrication

Pure Fabrication или чистая выдумка, или чистое синтезирование. Здесь суть в выдуманном объекте. Вот такой себе принцип-хак! Но без него никак. Аналогом может быть шаблон Service (сервис) в парадигме DDD.

Иногда, сталкиваемся с таким вопросом: «Какой объект наделить ответственностью, но принципы информационный эксперт, высокая сцепленность не выполняются или не подходят?». Тогда нужно использовать синтетический класс который обеспечивает высокую сцепленность. Тут без примера точно не разобраться.

Итак — ситуация. Какой класс должен сохранять наш объект Sale в базу данных? Если подчиняется принципу «информационный эксперт», то Sale , но наделив его такой ответственностью мы получаем слабую сцепленность внутри него. Тогда можно найти выход, создав синтетическую сущность — SaleDao или SaleRepository , которая будет сильно сцеплена внутри и будет иметь единую ответственность — и правильно сохранять Sale в базу.

Так как мы выдумали этот объект, а не спроектировали с предметной области, то и он подчиняется принципу «чистая выдумка».

Indirection

Indirection или посредник. Можно столкнуться с таким вопросом: «Как определить ответственность объекта и избежать сильной связанности между объектами, даже если один класс нуждается в функционале (сервисах), который предоставляет другой класс?» Необходимо наделить ответственностью объект посредник.

Например, возвратимся опять же MVC. UI-логике на самом деле нужен не контроллер, а модель, доменная логика. Но мы не хотим? чтобы UI-логика была сильно связанна с моделью, и возможно в UI мы хотим получать данные и работать с разной предметной логикой. А связывать UI-слой с бизнес логикой было бы глупо, потому что получим код который будет сложный для изменений и поддержки. Выход — вводим контроллер как посредник между View и Model.

Так что распределяйте ответственности всем своим объектам ответственно (с умом).

Protected Variations

Protected Variations или сокрытие реализации, или иначе защищенные изменения. Как спроектировать объекты, чтобы изменения в объекте или объекта не затрагивали других? Как избежать ситуации, когда меняя код одного объекта придется вносить изменения в множество других объектов системы?

Кажется мы такое обсуждали уже. И пришли к выводу, что нужно использовать low coupling или dependency injection. Именно! Но суть текущего принципа немного в другом. Суть в том, чтобы определить «точки изменений» и зафиксировать их в абстракции (интерфейсе). «Точки изменений» — не что иное, как наши объекты, которые могут меняться.

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

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

Polymorphism

Polymorphism или полиморфизм. Тоже знакомо, не так ли? Так вот это об том же полиморфизме, который мы знаем из ООП. Если заметить, то достаточно много паттернов GoF, да и вообще паттернов, построено на полиморфизме. Что он дает? Он дает возможность трактовать однообразно разные объекты с одинаковым интерфейсом (спецификацией). Давайте вспомним такие паттерны как Strategy, Chain of Resposibility, Command... — их много ещё всяких. И все по своей сути основываются на полиморфизме.

Полиморфизм решает проблему обработки альтернативных вариантов поведения на основе типа. Яркий пример этого — шаблон из GoF, — Strategy (Стратегия).

Например, для реализации гибкого функционала для шифрования можно определить интерфейс IEncryptionAlgorithm с методом Encrypt , и объект создатель, который вернет IEncryptionAlgorithm , создав внутри себя актуальную реализацию этого интерфейса.

Явно или неясно, пользуясь другими принципами или шаблонами — мы тоже часто используем принципы или шаблоны GRASP при разработке и проектировании. Многие принципы пересекаются, просто возможно разные авторы по-разному смещают акценты, но на удивление все принципы и шаблоны верны — и SOLID, и GRASP и классические GoF-паттерны — и многие другие. И все их следует использовать с умом и балансировать ними, применяя совместно с какими-то хаками под свою систему, что позволяет разрабатывать действительно красивые, устойчивые и гибкие архитектуры и приложения.

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

В заключение — принципы GRASP не создают четкую структуру, которой мы должны следовать в коде. Это больше глубоко продуманное распределение ролей и ответственностей между всеми объектами, а также свойства, которыми эти объекты должны обладать для того, чтобы гармонично исполнять свои роли

И как всегда в заключение, даю наводки на дополнительные материалы по рассмотренной сегодня теме:

Также для закрепления темы хорошая презентация на русском:

Читать дальше
Twitter
Одноклассники
Мой Мир

материал с blogerator.ru

6

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • pleshner
          • домен blogerator.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции