Золотое правило проектирования API Майкл Фезерс

Проектировать интерфейсы прикладного программирования (API) сложно, особенно в общем случае. Разрабатывая API, у которого будут сотни или тысячи пользователей, нужно думать о том, что со временем его, скорее всего, придется изменять, и эти изменения способны нарушить работу клиентского кода. Кроме того, нужно учесть возможное воздействие на ваш API со стороны его пользователей. Если класс API вызывает собственный метод, следует помнить, что пользователь способен создать подкласс вашего класса и переопределить этот метод, а это может привести к катастрофе. И вы не сможете изменить этот метод, потому что некоторые ваши пользователи придали ему другой смысл. Вы попадаете в зависимость от своих пользователей в том, что касается выбора внутренней реализации.

Разработчики API решают эту проблему разными способами, хотя проще всего заблокировать свой API. Скажем, в Java весьма соблазнительной может стать идея навешивать на большинство классов и методов модификатор final. В C#, в свою очередь, классы и методы можно объявить как sealed. В любом языке можно попробовать представить API с помощью синглтона или воспользоваться фабрикой статических методов для защиты от тех, кто попытается переопределить поведение и использовать ваш код способами, которые ограничат ваши возможности в будущем. Все это кажется разумным, но так ли это в действительности?

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

Положение со временем улучшится, но только если при проектировании API мы станем рассматривать тестирование как реальный сценарий использования. К сожалению, это несколько сложнее, чем просто тестировать наш код. Здесь уместно вспомнить золотое правило проектирования API: недостаточно написать тесты для разрабатываемого API; вы должны написать модульные тесты для кода, использующего ваш API. Следуя этому правилу, вы на собственном опыте узнаете, какие трудности ожидают ваших пользователей, когда они попытаются протестировать свой код самостоятельно.

Нет какого-то единого решения, облегчающего разработчикам тестирование кода на основе вашего API. Ключевые слова static, final и sealed по сути своей не являются плохими конструкциями. Иногда они бывают полезны. Но важно помнить о проблеме тестирования, а для этого вы должны испытать ее на себе. Как только это сделано, ее можно решать так же, как любую другую проблему проектирования.

Загрузка...