что такое ручка api
Что такое «ручка»?
Я вижу ссылки на дескрипторы окон, элементы управления, которые имеют ссылку на дескриптор окна и т.д. Но я не знаю, что такое дескриптор.
ОТВЕТЫ
Ответ 1
Вы можете это сделать. CWnd * pWnd = CWnd:: FromHandle (hWnd) Примечание: CWnd:: FromHandle (hWnd) является статическим и не требует экземпляра.
Он вернет вам обертку, в которую обернут hWnd. Ну не совсем! Если дескриптор на самом деле не обернут объектом, он создаст один, И ЭТО БУДЕТ ТОЛЬКО ВРЕМЕННО. Так используйте его один раз, а затем выбросьте его. Он может создать экземпляр, поскольку hWnd имеет достаточно информации в своей структуре для окон, чтобы создать экземпляр объекта CWnd. Он не добавляет его в таблицу элементов управления v, поэтому он является временным.
HWND на самом деле является объектом ядра и больше? HWND (CWnd и CWnd-производные классы) HDC (классы CDC и CDC) HMENU (CMenu) HPEN (CGdiObject) HBRUSH (CGdiObject) HFONT (CGdiObject) HBITMAP (CGdiObject) HPALETTE (CGdiObject) HRGN (CGdiObject) HIMAGELIST (CImageList) SOCKET (CSocket) (должен был быть HSOCKET?) + Другие. Я не уверен, что все они возвратят временный объект, если потребуется. GetDC (hWnd) доставит вам hDC из hWnd, но он будет временным, возможно, лучше использовать CDC claa.
Ответ 2
Дескриптор представляет собой абстрактную ссылку на какой-либо ресурс, предоставленный вам другой стороной (как правило, ОС), которую вы можете вернуть для ссылки на этот ресурс.
ОС часто содержат таблицу дескрипторов, содержащую объекты, созданные пользователями (открытые файлы. ); дескриптор представляет собой целочисленный индекс в эту таблицу. Ваш процесс делает открытым, ОС создает запись в своей таблице дескрипторов, маркирует ее своим именем (процессом) и передает индекс этой записи обратно в ваш процесс. Когда ваш процесс хочет выполнить чтение, он предоставляет целое число дескрипторов для ОС, которое просматривается в таблице, просто используя его в качестве индекса таблицы; теперь он знает, какой объект (файл) хочет обработать ваш процесс.
Поместив свой идентификатор процесса в запись дескриптора, ОС может определить, действителен ли дескриптор для процесса. Ваш процесс может предоставить мусор в качестве дескриптора ОС; если слот ручки совпадает, ОС будет делать то, что вы хотите, независимо от того, насколько это глупо. В конце концов, это ваш ресурс.
Ответ 3
Что такое «ручка»?
Я часто слышал о “дескрипторах”, что это такое?
Изменить:
Например, я слышал о:
оконные ручки
обработчики событий
файловые дескрипторы
и т.д. Это то же самое? Или это некоторые абстрактные термины?
Ручка – это косвенный способ ссылки на объект, принадлежащий ОС или библиотеке. Когда операционная система или библиотека владеет объектом, но хочет, чтобы клиент ссылался на него, он может предоставить ссылку на этот объект, называемый дескриптором.
Ручки могут быть реализованы по-разному. Обычно они не являются ссылками в смысле С++ или С#. Часто они представляют собой указатели на какой-то непрозрачный тип, или они могут быть (или содержать) индекс в таблицу объектов, принадлежащих операционной системе или библиотеке.
Например, в Windows, если вы создаете окно, ОС создает объект, который представляет это окно, но не возвращает указатель на этот объект. Вместо этого он возвращает дескриптор окна, который обеспечивает дополнительный слой косвенности. Когда вы передаете дескриптор окна обратно в другой вызов ОС, ОС знает, какой объект окна использовать на основе дескриптора. Это не позволяет вашему коду напрямую обращаться к объекту окна.
Дополнительный слой косвенности позволяет операционной системе или библиотеке делать такие вещи, как перемещать объекты, ссылаться на объекты и обычно контролировать, что происходит с объектом. Подобно идиоме PIMPL, реализация может полностью измениться, сохраняя при этом первоначальный API и, таким образом, не заставляя клиенты перекомпилировать. Это особенно полезно, если вы пытаетесь предложить не-объектно-ориентированный API для клиентов, написанных на процедурных языках, таких как C.
“handle” – это другое имя для ссылки на ресурс, который управляется программистом явно, а не автоматически с помощью среды выполнения.
Ручки – это указатели на неуправляемые ресурсы, такие как дескрипторы файлов, дескрипторы подключения к базе данных, дескрипторы окон и т.д. Поскольку они являются ручками для неуправляемых ресурсов, в большинстве случаев они не будут автоматически собираться с мусором, и вам необходимо обеспечить надлежащий выпуск их или вы можете услышать об утечках ручек.
Интеллектуальные ручки пользовательского объекта в MultiCAD.NET
Удобство редактирования чертежей является одной из ключевых характеристик систем автоматизированного проектирования. Важным инструментом для работы с объектами чертежа служат ручки (grips) — специальные маркеры в ключевых точках объекта, которые позволяют видоизменять объект с помощью мыши, без использования меню или командной строки.
Механизм управления ручками в MultiCAD.NET позволяет работать как с простыми, так и интеллектуальным ручками. Про простые ручки мы писали в одной из прошлых статей, здесь же мы рассмотрим интеллектуальные ручки, которые, помимо формы (круглые, треугольные, ромбовидные и т.д.), отличаются от простых тем, что они могут изменять отдельные параметры объекта, вызывать всплывающее меню или выполнять набор действий, определенный в обработчике. Кроме, этого API интеллектуальных ручек позволяет также создавать и простые ручки, но используя при этом новый, унифицированный подход.
Под катом код создания нескольких видов интеллектуальных ручек объекта и анимированные изображения, демонстрирующие их использование.
Класс McSmartGrip
Регистрация ручек
Регистрация ручек пользовательского объекта производится с помощью метода AppendGrip() класса GripPointsInfo :
Следующий фрагмент кода создает и добавляет всю ту же простую ручку:
Как видите, вся процедура очень компактна и занимает всего одну строку кода. Однако, это касалось самого элементарного случая, а именно, простых ручек. Давайте рассмотрим какие еще типы ручек поддерживаются в MultiCAD.NET API, а также специфику работы с каждым из них.
Типы ручек
Внешний вид ручек
Простая ручка
Этот вид ручек мы уже упоминали в статье, и, как можно догадаться из названия, он используется для простых действий, например, для перемещения точек объекта. Добавим одну простую ручку для перемещения угловой точки нашего примитива:
Результат работы такой ручки — на анимированной иллюстрации:
Ручка-кнопка
Добавим ручку-кнопку, которая будет управлять отображением рамки вокруг текста по нажатию. Для создания такой ручки используется конструктор с указанием типа ручки McBaseGrip.GripType.Button и базовым цветом. Обработчик нажатия на кнопку OnCommand меняет значение индикатор рисования рамки _show_frame на обратное. Для созданной ручки-кнопки определим внешний вид «включено», который будет меняться на «выключено» при нажатии, и обратно.
Также по нажатию ручки-кнопки может быть вызвана необходимая зарегистрированная команда:
Что такое «ручки» на сленге программистов?
Например, смотря видео с различных конференций Яндекса, можно часто слышать это слово.
Ну в том числе у нас есть такие ручки, в том числе продуктовые ручки, когда нужно чтобы в определенный момент в браузере что-то замигало. Ну вот это не сильно нагруженные ручки. Очень нагруженные ручки мы стали писать на плюсах.
4 ответа 4
К handle никакого отношения не имеет. К UML возможно тоже, т.к. он в документации не используется.
Подозреваю, это может быть как-то связано с внешним видом реализуемых компонентом интерфейсов в UML, которые выглядят как рукоятки в механике/гидравлике:
Всё ещё ищете ответ? Посмотрите другие вопросы с метками терминология или задайте свой вопрос.
Похожие
Подписаться на ленту
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.11.26.40833
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Бэкенд для фронтенда, или Как в Яндекс.Маркете создают API без костылей
Почему некоторыми API удобнее пользоваться, чем другими? Что мы как фронтендеры можем сделать на своей стороне, чтобы работать с API приемлемого качества? Сегодня я расскажу читателям Хабра как о технических вариантах, так и об организационных мерах, которые помогут фронтендерам и бэкендерам найти общий язык и наладить эффективную работу.
Этой осенью Яндекс.Маркету исполняется 18 лет. Все это время развивается партнерский интерфейс Маркета. Если кратко, то это админка, с помощью которой магазины могут загружать каталоги, работать с ассортиментом, следить за статистикой, отвечать на отзывы и т.д. Специфика проекта такова, что приходится очень много взаимодействовать с различными бэкендами. При этом данные не всегда можно получить в одном месте, из одного конкретного бэкенда.
Симптомы проблемы
Потом менеджер идет к фронтендеру со словами «я тебе API принес» и предлагает все по-быстрому заскриптовать, т. к., по его мнению, почти вся работа уже сделана.
Вы смотрите на документацию и видите это:
Не замечаете ничего странного? Camel, Snake и Kebab Case в рамках одной ручки. Я уже не говорю про параметр fesh. Что вообще такое fesh? Такого слова даже не существует. Попробуйте догадаться до того, как раскроете спойлер.
Fesh — это фильтр по ID магазина. Можно передать несколько айдишников через запятую. Перед ID может идти знак минус, что означает, что надо исключить этот магазин из результатов.
При этом из JavaSctipt’а, понятное дело, я не могу получить доступ к свойствам такого объекта через точечную нотацию. Не говоря уже о том, что если у вас больше 50 параметров у одного плейса, то, очевидно, вы в своей жизни повернули куда-то не туда.
Вариантов неудобного API очень много. Классический пример — API осуществляет поиск и возвращает результаты:
Если товары найдены — получаем массив. Если найден один товар, то получаем объект с этим товаром. Если ничего не найдено, то в лучшем случае получаем null. В худшем случае бэкенд отвечает 404 или вообще 400 (Bad Request).
Бывают ситуации проще. Например, вам нужно получить список магазинов в одном бэкенде, а параметры магазина — в другом. В каких-то ручках данных не хватает, в каких-то данных слишком много. Фильтровать все это на клиенте или делать множественные аякс-запросы — плохая идея.
Итак, какие могут быть пути решения этой проблемы? Что мы как фронтендеры можем сделать на своей стороне, чтобы работать с API приемлемого качества?
Бэкенд для фронтенда
Мы в партнерском интерфейсе используем на клиенте React/Redux. Под клиентом лежит Node.js, который делает много вспомогательных вещей, например прокидывает на страницу InitialState для Редакса. Если у вас сервер-сайд рендеринг, не важно с каким клиентским фреймворком, скорее всего, он рендерится нодой. А что, если пойти на шаг дальше и не обращаться с клиента напрямую в бэкенд, а сделать свое проксирующее API на ноде, максимально заточенное под клиентские нужды?
Эту технику принято называть BFF (Backend For Frontend). Впервые этот термин ввел SoundCloud в 2015 году, и схематично идею можно изобразить в таком виде:
Таким образом, вы перестаете с клиентского кода ходить напрямую в API. Каждую ручку, каждый метод реального API вы дублируете на ноде и с клиента ходите исключительно на ноду. А нода уже проксирует запрос в реальное API и возвращает вам ответ.
Помните тот пример с result-ом, когда бэкенд возвращал null, массив или объект? Теперь мы можем привести его к нормальному виду — чему-нибудь вроде такого:
Этот код выглядит ужасно. Потому что он ужасен. Но нам все равно нужно это сделать. У нас выбор: делать это на сервере или на клиенте. Я выбираю сервер.
Также мы можем мапить все эти кебаб- и снейк-кейсы в удобный нам стиль и тут же проставлять значение по умолчанию в случае необходимости.
Какие еще плюсы мы получаем?
Чтобы нивелировать эти минусы, достаточно придерживаться простых правил. Первое — разделять интерфейсную и бизнес-логику. Ваш BFF не должен менять бизнес-логику основного API. Второе — ваша прослойка должна преобразовывать данные только в случае крайней необходимости. Мы говорим не о самодостаточном всеохватывающем API, а только о проксе, которая заполняет пробел, исправляя недостатки бэкенда.
GraphQL
Похожие проблемы решает GraphQL. С GraphQL вместо множества «глупых» endpoint у вас одна умная ручка, которая умеет работать со сложными запросами и формировать данные в том виде, в котором их запрашивает клиент.
При этом GraphQL может работать поверх REST, т. е. источником данных служит не база, а рестовое API. За счет декларативности GraphQL, за счет того, что все это дружит с Реактом и Редаксом, ваш клиент становится проще.
На самом деле, GraphQL мне видится реализацией BFF со своим протоколом и строгим языком запросов.
Это отличное решение, но у него есть несколько недостатков, в частности, с типизацией, с разграничением прав, и в целом это относительно свежий подход. Поэтому мы на него пока не перешли, но в перспективе это кажется мне самым оптимальным способом создания API.
Best Friends Forever
Ни одно техническое решение не будет правильно работать без организационных изменений. Вам все равно нужна документация, гарантии того, что формат ответа внезапно не изменится и т. д.
При этом нужно понимать, что все мы в одной лодке. Абстрактному заказчику, будь то менеджер или ваш руководитель, по большому счету без разницы — GraphQL у вас там или BFF. Ему важнее, чтобы задача была решена и на проде не всплывали ошибки. Для него нет особой разницы, по чьей вине возникла ошибка в проде — по вине фронта или бэка. Поэтому нужно договариваться с бэкендерами.
К тому же изъяны бэка, о которых я говорил в начале доклада, не всегда возникают из-за чьих-то злонамеренных действий. Вполне возможно, что и у параметра fesh есть какой-то смысл.
Обратите внимание на дату коммита. Получается совсем недавно fesh отметил свое семнадцатилетие.
Видите какие-то странные идентификаторы слева? Это SVN, просто потому что в 2001 году гита не было. Не гитхаба как сервиса, а именно гита как системы управления версиями. Он появился только в 2005 году.
Документация
Итак, все, что нам нужно — не ссориться с бэкендерами, а договориться. Это можно сделать только если мы найдем один единственный источник правды. Таким источником должна быть документация.
Самое главное здесь — написать документацию до того, как мы начнем работать над функциональностью. Как с брачным договором, лучше обо всем договориться на берегу.
Как это работает? Условно говоря, собираются трое: менеджер, фронтендер и бэкендер. Фронтедер хорошо разбирается в предметной области, поэтому его участие критически важно. Они собираются и начинают думать над API: по каким путям, какие ответы должны возвращаться, вплоть до названия и формата полей.
Swagger
Хороший вариант для документации API — формат Swagger, сейчас он называется OpenAPI. Лучше использовать Swagger в YAML-формате, т. к., в отличие от JSON, он лучше читается человеком, а для машины разницы нет.
В итоге все договоренности фиксируются в Swagger-формате и публикуются в общий репозиторий. Документация на продовый бэкенд должна лежать в мастере.
Мастер защищен от коммитов, код в него попадает только через пул реквесты, пушить в него нельзя. Представитель фронт-команды обязан проводить ревью пул реквеста, без его апрува код в мастер не едет. Это защищает вас от неожиданных изменений API без предварительного уведомления.
Итак, вы собрались, написали Swagger, таким образом фактически подписали контракт. С этого момента вы как фронтендер можете начинать свою работу, не дожидаясь создания реального API. Ведь в чем был смысл разделения на клиент и сервер, если мы не можем работать параллельно и клиентским разработчикам приходится ждать серверных разработчиков? Если у нас есть «контракт», то мы можем спокойно параллелить это дело.
Faker.js
Для этих целей отлично подходит Faker. Это библиотека для генерации огромного количества фейковых данных. Она умеет генерировать разные типы данных: даты, имена, адреса и т. д., все это хорошо локализуется, есть поддержка русского языка.
При этом фейкер дружит со свагером, и вы можете спокойно поднять моковый сервер, который на основе Swagger-схемы будет генерировать вам фейковые ответы по нужным путям.
Валидация
Swagger можно сконвертировать в json-схему, и с помощью таких инструментов как ajv вы можете прямо в рантайме, в своем BFF, валидировать ответы бэкендов и в случае расхождений репортить тестировщикам, самим бэкендерам и т. д.
Допустим, тестировщик находит на сайте какой-то баг, например при клике на кнопку ничего не происходит. Что делает тестировщик? Ставит тикет на фронтендера: «это ведь ваша кнопка, вот она не нажимается, чините».
Если между вами и бэком стоит валидатор, то тестировщик будет знать, что кнопка на самом деле нажимается, просто бэкенд присылает неправильный ответ. Неправильный — это такой ответ, который фронт не ожидает, т. е. не соответствующий «контракту». И тут уже надо или чинить бэк или менять контракт.