В докладе говорится о проектировании архитектуры API — начиная с того, о ком должен думать разработчик в начале работы, и до секретов «безболезненного» рефакторинга. От общей культуры формирования интерфейсов до правки багов и поддержки обратной совместимости. А также пара слов о документации — фасаде любого API.
11. 11
300 000 сайтов используют API
15 000 000 пользователей видят карту
через API ежедневно
(это каждый 10-й человек в России)
12. 12
Про что я буду рассказывать
! В чем основная проблема разработки API
! Приемы проектирования, которые мы применяем, чтобы с этой
проблемой жить
13. 13
Бонус!
Я буду приводить примеры, когда мы не соблюдали собственные
рекомендации и сильно от этого страдали
Слайды стыда и позора будут помечены специальным знаком
23. 23
Чего хочет этот пользователь?
API
Пользовательский код,
работающий с API
Проект
Написал,
отладил и
забыл
24. 24
Если вы ломаете обратную совместимость, пользователь
вынужден вечно переписывать код
1.1.0
1.1.1
1.1.2
Пользовательский код №0
Пользовательский код №1
Пользовательский код №2
Проект
25. 25
И ЕМУ ЭТО НЕ НРАВИТСЯ
Если вы ломаете обратную совместимость, пользователь
вынужден вечно переписывать код
43. 43
Каждый уровень – это информационный
контекст
Геообъект
Геометрическая
модель
DOM-макет
Здесь важны
координаты,
проекция, зум
Здесь важны
пиксельные
координаты окна
карты
50. 50
Взаимодействие на событиях
«Я подвинулась»
«Карта подвинулась, надо бы
перерисоваться»
«Так, говорят надо
перерисовываться, двигай наш div»
Геообъект
Геометрическа
я модель
DOM-макетКарта
59. 59
Плюсы взаимодействия на событиях
! Слабая связанность объектов
! Легко «подцепить» новую сущность
! Абстрагируетесь от соседей
! Можно реагировать на события частично
60. 60
Что мы узнали про уровни абстракции
! Нужно выстроить иерархию взаимодействия
! Уровни знают только о своих соседях
! Уровень – это информационный контекст
! Максимально разграничиваем обязанности
! Взаимодействие уровней через события
61. 61
Мы строили, строили и наконец построили -
Наша система состоит из множества небольших сущностей,
взаимодействующих между собой.
62. 62
Мы строили, строили и наконец построили -
Наша система состоит из множества небольших сущностей,
взаимодействующих между собой.
Это надо отметить описать!
64. 64
Что такое программный интерфейс?
! Описание функциональности, которую предоставляет
компонент. Причем в определенном контексте.
!
IChild!
!.getParent() // Описание методов.!
!.setParent()!
!@parentchange // Описание событий. !
!
67. 67
Вспомним пример, в котором мы хотели
заменить один из компонентов
Геообъект
Геометрическая
модель
DOM-макет
Canvas-макет
68. 68
Как понять, насколько точно нам надо скопировать заменяемую
сущность, чтобы система не рухнула?
DOM-макет
Canvas-макет
69. 69
Если вы описываете интерфейсы, проблем
такого рода не возникает
IGeoObject IOverlay ILayout
На это место можно поместить
любую реализацию интерфейса
70. 70
Какие задачи решают программные
интерфейсы
! Вы получаете формальное описание вашей системы
! Сущности становятся легко заменяемыми (подойдет любая
реализация интерфейса)
71. 71
! Когда вы продумываете
программные интерфейсы,
вы наводите порядок у
себя в голове
72. 72
Интерфейсы должны быть дробными
ICollection
IParentOnMap
ymaps.Collection
ymaps.GeoObjectCollection
73. 73
Если в вашем интерфейсе много сущностей
- это повод задуматься
setParent()
getParent()
.options
.events
IChild
ICustomizable
IEventEmitter
76. 76
Грустный пример из реальной жизни
www.somesite.ru?%с&%n&%l&%j%s
Для расшифровки этого url нужно выучить небольшой
нелогичный алфавит:
%c – coordinates
%l – lang
%n – layer (ну потому что %l занято)
%j – id (пошло от «jam»)
%s – timestamp (потому что «stamp»)
90. 90
Подставим интерфейсы в схему
ICollection
cluster.getGeoObjects()
IGeoObject
IGeoObject IGeoObject
IGeoObject
IGeoObject
IGeoObject
IGeoObject
IGeoObject
IGeoObject
IGeoObject
Этот метод больше нельзя
использовать – он
не входит в интерфейс
91. 91
Как реально выглядит процесс
1. Выделяем уровни абстракции
2. Пишем код
3. Описываем получившиеся интерфейсы
4. Переписываем код, чтобы все сущности использовали только
интерфейсные методы
92. 92
Вариант №2 (правильный)
1. Выделяем уровни абстракции
2. Описываем интерфейсы
3. Пишем код, в котором объекты взаимодействуют через
интерфейсные методы, поля, события
95. 95
Мы не успели отточить интерфейсы
контролов при запуске
Контролы писали разные люди, в результате
получили немного разные конструкторы
Button(params, options)!
TrafficControl(state, options)!
SearchControl(options)!
96. 96
Обратная сторона интерфейсов
! Из-за того, что объекты
станут композициями дробных
интерфейсов, конечные
объекты могут иметь несколько
монструозный и избыточный
интерфейс.
97. 97
У нас чудесным, но монструозным вышел
IGeoObject
! var myPlacemark = new ymaps.GeoObject({!
! !geometry: { !
! ! !type: “Point”,!
! ! !coordinates: [37.61, 55.75] !
! !},!
! !properties: {!
! ! !balloonContent: ‘Hello!’,!
! ! !id: 723!
! !}!
!}, {!
! !// Опции.!
! !preset: ‘twirl#redIcon’,!
! !zIndex: 100!
!});!
100. 100
Также вас спасут значения по умолчанию
Программист изучает опции геообъекта только в тот момент,
когда они ему понадобятся и не забивает голову ненужным
мусором