Объектно-ориентированное про…ектирование?

Vanilla Thunder
DesignSpot

--

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

«И помните, последнее задание на 9–10 баллов — описать основные принципы и парадигмы ООП», — говорит она и улыбка оголяет её острые жёлтые зубы. Она знает, что мы не знаем, но знаем, что она знает, что мы не знаем. И от этого страдание ещё вкуснее.

«Про иерархию, абстракцию и наследование ещё можно догадаться, но полиморфизм и инкапсуляция… кто вообще придумал эти слова?!», — звучит голос у меня в голове. Звонок. Пора сдавать листики с кодом, чтобы микропроцессор в голове у преподавательницы закомпилил наши шедевры и выплюнул результат в зачётки. Тогда я получил 7 и это был первый курс универа. Кто знал, что эти незнакомые слова всплывут через столько лет, но уже в проектировании интерфейсов.

Что такое ООП?

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

В сопряжении сфер и рождается новое знание, когда идеи перетекают из одного домена в другой, но я никогда не думал, что дело дойдёт до ООП. Дошло. И это вдохновляет. Так что это за зверь?

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

→ Открыть этот пост,

→ Прочитать пост,

→ Похлопать в ладоши,

→ Поделиться ссылкой.

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

Disclaimer: и да простят меня приверженцы всех других парадигм программирования и опустят свои тухлые помидоры, ибо сейчас речь не о них.

Посмотрите вокруг себя, вас со всех сторон окружают предметы: рядом со мной лежит пёс, подо мной ковёр, рядом кровать, часы, шкаф — всё это объекты, которые обладают какими-то свойствами, и с которыми я могу что-то делать (или они делают что-то сами). Например, я могу вызвать метод СколькоХлама у шкафа и узнать, сколько там одежды, могу переопределить свойство виляния хвостом у пса или обратиться к API часов и узнать, который час.

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

→ Если нажали на карточку 1 → Добавить в корзину товар 1,

→ Если нажали на карточку 2 → Добавить в корзину товар 2,

Достаточно было просто создать специальный класс «Карточка», у которого было бы свойство «Товар» и метод «Добавить в корзину». И всё, что оставалось сделать, так это насоздавать экземпляров этого класса, и вуаля — каждая карточка делает нужное действие. Пример утрирован, конечно, там ещё очень много всего супер-сложного, но суть, надеюсь, ясна.

Каждый класс может обладать свойствами и реализовывать методы.

Свойство — это атрибут, присущий всем экземплярам класса. Или проще «Что содержит в себе объект?». Вот калимба. Какими свойствами она обладает? Материал, количество липестков, наличие резонатора, степень настройки. А вот мой пёс. Что у него? Режим работы (сон или пытка), количество вылиняной шерсти, степень голода, длина когтей — всё это свойства.

Метод — это действия, которые можно произвести с объектом (или действия, которые выполняет он сам). А какие методы реализует калимба? Извлечь звук, настроить ноту молотком, успокоить разум медитацией. А пёс? Вилять хвостом, скулить, смотреть жалобными глазами (принимает константу «Хозяин»), дрожать, поглощать объекты (принимает любой объект, можно не съедобный), лаять (по умолчанию выставлена степень чувствительности «Пук белки в радиусе 3 км») и т.д. — всё это методы моего пса.

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

Причём тут дизайн?

Да собственно при том, что сейчас набирает популярность такой подход к проектированию, как OOUX (Object Oriented UX), который по сути своей базируется на парадигме описанной выше.

Sophia V. Prater в своей статье 2015 года предложила отойти от привычного процесса проектирования экранов и обратить внимание на Объекты, на которых всё строится.

Уже успела устареть сама мысль о том, что наш подход к проектированию устарел. Пора бы уже перестать начинать дизайн с того, чтобы рисовать страницы-прямоугольники и фаршировать их контентом под фразу «Ну, наверное вот это должно быть на тут», а потом «Блин, забыл, нужно же ещё вот это…». Бывало у вас такое? У меня, например, уходило не одна итерация скетчинга, чтобы всё устаканить. Хотя я и считаю, что скетчинг, на то и скетчинг, чтобы быстро итерировать. Но ведь можно это делать эффективнее.

Отход от экранного мышления неизбежен, ведь взаимодействие выходит далеко за рамки монитора, а проектирование обязано покрывать все закоулки пользовательского опыта. И если вы ещё думаете «Нужно сделать главную, потом корзину, потом карточку товара…», то у меня для вас новости: вы ходите по тонкому льду, рискуя упустить что-то важное.

У вас не было такого чувства, что в нашем процессе чего-то не хватало. Но даже несмотря на это паучье чутьё, мы не знали, как делать работу иначе, потому экранное мышление просуществовало так долго. Но это не значит, что OOUX взял родился в одночасье. Ещё до того, как я услышал это модное словцо, я занимался чем-то подобным, рисуя flow взаимодействия с прописью всех компонентов и данных в них. Но как это называется, я не знал. Я в этом не одинок. Все дизайнеры, рано или поздно, начинают задумываться над тем, что им понадобиться для успешного завершения процесса, просто делают это по-разному.

Пример псевдо OOUX вшитого в microframe

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

🌪 Классический пример

Давайте разберем на одном примере два процесса проектирования и сравним их. На одной чаше весов будет экранное мышление, а на другой — OOUX, подход предложенный Софией. Рассматривать мы будем проектирование сервиса для аренды кваритир.

Ещё до того, как я стал ярым пропагандистом сторифрейминга, то есть словарного описания ментальной модели пользователя, мой процесс выглядел приблизительно так. Приходит задача:

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

«Ну и что тут сложного», — думаю я, — «нам просто нужен листинг из карточек-предложений, возможно, предложу карту, как паттерн для более эффективного выбора, фильтры там будут сверху (просто дроп-дауны), на карточках обязательно фото, описание, рейтинг, стоимость… Ну как-то так.» Оторвав лайнер от бумаги, можно насладиться своим трудом. В лучших традициях дриббблоделов, кайф!

Простите за детализацию, но это просто пример 🙂

Ну всё, расчихляем фигму. Хотя можно было бы прорисовать ещё пару экранов и переходы между ними, соорудив полноценный микрофрейм, но в нашем случае…

За этим следовали несколько итераций в редакторе, демо и открытое шампанское. Но если этот процесс знаком и вам, вы должны помнить, как ваше ликование разбивалось о скалы «новых обстоятельств». Как пришёл БА и жёстким подзатыльником выбил клубнику изо рта и сказал: «У нас описание объекта в триста строк сгенерировано искусственным интеллектом AliExpress, карта не работает, как и рейтинг, фоток пока нет, арендовать объект нельзя, можно только посмотреть номер арендодателя… и вообще, мы теперь шаурму продаём». Знакомо? Что вы вздыхаете? Все там были.

☀️ OOUX на практике

Теперь давайте посмотрим, что произойдёт, если сперва задуматься об объектах, их свойствах и методах. Вместо того, чтобы хвататься за карандаш… Не, ну карандаш давайте всё-таки возьмём, но не будем рисовать прямоугольники, а начнём писать.

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

Выделяем объекты

Откуда вообще берутся объекты? В основном, из целей и задач пользователя, которые хорошо бы определить заранее. В нашем случае, на поверхности лежат минимум 3 объекта: мы хотим найти лучший вариант жилья, значит у нас всенепременно будут объявление, арендодатель и арендатор со всеми его просмотренными объявлениями, контактами, интересами и остальными атрибутами.

Хотя есть здесь свой подвох: просто на целях или JTBD сконцентрироваться не получится. Так или иначе придётся создавать сторифрейм или пользовательские истории, чтобы понять, как целей достигнуть, и с какими объектами придётся столкнуться по-пути.

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

Далее в примере я буду использовать только объект «Объявление», для простоты восприятия.

Определяем наполнение объектов

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

Золотого правила, как определить набор свойств нет — слушайте своё сердце, здравый смысл и user flow, задаваясь вопросом «на основе чего будет приниматься решение?»

И здесь нас поджидает первый принцип ООП — Абстракция. Суть его в том, что объект не нужно описывать максимально детально, нужно руководствоваться минимальным достаточным набором. Для тех, кто хоть когда-нибудь что-нибудь покупал онлайн: для объекта «Заказ», с точки зрения взаимодействия, не важен вес посылки, если только на него не завязана стоимость доставки. Как и неважен логистический маршрут и имя водителя фуры, главное — дата поставки. Хотя никто не мешает набрейнстормить все-все возможные свойства, а потом урезать лишнее—тоже неплохо работает.

Для нашего примера я позволил накидать себе немного свойств и методов «из головы». Как вы понимаете, здесь описаны только мои предположения, которые по-идее, должны будут стать свалидированными гипотезами. Но пока и рак рыба.

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

Определяем связи и вложенность компонентов

Закономерным шагом в процессе определения свойств будет создание иерархии или вложенности объектов друг в друга. Например, избранные объявления в объекте «Арендатор».

Иерархия поможет увидеть преемственность данных в системе и сможете понять в каких контекстах и что будет реиспользовано. Здесь стоит упомянить о Наследовании, как о способе упорядочивания системы. Если коротко, то это способ организации, при котором мы «выносим за скобки» всё общее, а в объектах оставляем уникальное. Аналогия из биологии: какой-то набор свойств вы унаследовали от отца, а какие-то свойства приобрели самостоятельно. Отец ваш, как и вы, в свою очередь, являетесь представителями млекопитающих с парным набором конечностей, которые в свою очередь наследуются… ну вы поняли.

Давайте предствим, что у нас на сервисе будет присутствовать два разных типа объявлений: долгосрочная и краткосрочная аренда (посуточно). Можно было бы рассматривать их как один объект «Объявление», нафаршировав его всем возможным набором свойств и методов для каждого типа. Однако, если различия слишком большие—отзывы и рейтинг на саму квартиру гораздо более важны при посуточной аренде, а для долгосрочной гораздо более ценны мнения о хозяине; где-то котируется цена за месяц, а где-то за сутки; удалённость от центра или близость к достопримечательностям и т.д. Тут лучше воспользоваться наследованием.

Несмотря на различия, сходства ведь тоже есть. И что делать? В таком случае можно поступить следующим образом: создать объект «Объявление», куда положить все схожие свойства и методы, а от него унаследовать ещё два объекта «Посуточное объявление» и «Долгосрочное объявление». Так вы сможете вынести за скобки всё общее и избежать избыточности и дубликатов.

Приоритезируем свойства

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

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

Определяем CTA-inventory

Как только свойства устаканились, можно переходить к методам, то есть к тому, что с нашим объявлением можно делать.

А чтобы не думать, с чего начать, и сразу смазать свои мозго-шестерни, то вот вам одно определение, которое я перенял из программирования — CRUD. Это акроним методов, который должны поддерживать все объекты, хранимые в базах данных: создание (Create), чтение (Read), обновление (Update), удаление (Delete). С этого можно начать, но не останавливаться, ведь CTA-inventory (такое название придумали методам объекта) должен адаптироваться под ваши конкретные нужды.

И здесь нам снова поможет Flow map, дабы понять, все-ли действия покрыты и можно-ли попасть о все части сценария. В этом процессе могут возникнуть дополнительные свойства, которые нужно добавить в перечень. Например, метод добавления в избранное породит свойство «объявление в избранном или нет».

Чувствуете? Как-то все просто. Давненько никакой заумный принцип не всплывал. А вот и он — Инкапсуляция. Дело в том, что свойства и методы не могут существовать вне объекта, иначе они перестануть быть свойствами. А значит, если что-то где-то происходит, значит это кому-то нужно.

Тот же метод добавления объявления в избранное будет частью объекта… «Пользователь», ибо именно в нём будут храниться ссылки на все «залайканые объявления», а не в объявлении айдишники всех пользователей, которые его залайкали.

Определяем контекст

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

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

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

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

И казалось бы, всё супер, пора возрадоваться и переносить всё на бумагу. И вы будете правы. Ну как вам новый подход? Мне очень нравится, но не смотря на все достоинства, подход не лишён своих недостатков.

🤔 Реальность шепчет

Каким бы логичным и правильным не показался OOUX, в реальности, как вы понимаете, нет чистого чёрного и чистого белого. Я решил затестить подход в боевых условиях (проект финансового домена), а не на поварах и макаронах, и посмотреть, что из этого получится.

Со старта начали вылезать камушки, например, нельзя просто взять и сказать «мне нужно это и это», ибо ты не знаешь, что тебе понадобиться на пути, пока ты его не создашь. Так или иначе, приходится строить сторифрейм или user flow, который уже вбирает в себя части OOUX — получается слегка двойная работа. То есть, начинать с OOUX сложные проекты не получится, а вот продолжать вполне себе можно.

Продолжая испытания выяснилось, что в одиночку проект из незнакомого домена потянуть будет невозможно, так как приоритетный набор свойств будет вам неизвестен, а «из головы» генерить их можно просто бесконечно. Конечно, в нашем случае нам помогли консультации экспертов, а вам могут помочь и воркшопы, но как вы понимаете, не везде есть ресурсы на всё это.

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

Ну и завершающий недостаток — неприменимость подхода в проектировании процессов, где скорее важно не «что», а «куда» и «как». Здесь скорее подойдёт функциональное проектирование, но это уже совсем другая история.

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

Памятка по объектно-ориентированному проектированию

или как OOUXить

  1. Определитесь с объектами в вашей системе,
  2. Наполните объекты свойствами (Абстракция),
  3. Выстройте иерархию и используйте наследование,
  4. Приоритезируйте ваши свойства,
  5. Определите методы (CTA-inventory), помня про инкапсуляцию,
  6. Адаптируйте ваш объект под все контексты использования: состояния и представления (Полиморфизм).

Далее по теме

Первая часть оригинальной серии статей об объектно-ориентированном проектировании от Софии,

Вторая часть про определение методов (на русском),

— О важности перехода к новой модели мышления,

— Чуть-чуть программирования и трансформеров в ООП.

На этом все. Чуть было не забыл порекламировать свой канальчик в телеге, где нет рекламы и только мысли и отборный контент.

Теперь точно всё. Прекрасного вам настроения, простых объектов с шикарными свойствами и понятными методами. Счастья-здоровья и корабль любви. 🛳❤️

--

--

DesignSpot
DesignSpot

Published in DesignSpot

It's community for researchers, interface and experience designers and ones who interested in this theme.

Vanilla Thunder
Vanilla Thunder

Written by Vanilla Thunder

Dmitry Vanitski, Principal UX Designer, Lithuania

No responses yet