Что такое полимофризм? В одном из комментариев в постах про паттерны, кто-то сказал что совсем не въезжает в полиморфизм. Тогда я понял что надо немного откатиться и рассказать, так как концепция важна и без нее понимание многих вещей, например, тех же паттернов, будет нереальным. Так что садитесь по удобнее и слушайте) Сначала договоримся что под словом полиморфизм здесь мы понимаем полиморфизм подтипов или сабтайпинг, это то что называется полиморфизмов в ооп. Кроме него есть и другие, о которых, может быть, в другой раз (например, дженерики это пример параметрического полиморфизма) Если в двух словах, то полиморфизм позволяет нам подменять реализацию без необходимости переписывать код. Проявляется это по разному в разных ситуациях и чтобы увидеть картинку целиком, нужно разобрать эти типовые ситуации. Но есть проблема, если у бекендеров полиморфизм по всюду хотят оно того или нет, то у фронтендеров его мало если это не angular, где он вшит через контейнер во фреймворк. Попробуем, все же, зайти через фронтенд, надеюсь будет понятно. Допустим мы работаем с беком по апи и для этого используется спец либа, а не просто fetch запросы. У гитхаба есть подобная либа: https://github.com/octokit/rest.js Дальше вы решили написать тесты к своему коду и столкнулись с проблемой, что в тестах улетают запросы на реальный github, что не правильно. В тестах во внешние системы не ходят (кстати вы знаете почему?). Как выйти из этой ситуации? • Либа может сама содержать такую функциональность. Ставится какой-нибудь флаг и она не шлет запросы • Подход, который довольно популярен в JavaScript (и Ruby) это манки патчинг. С помощью либы https://github.com/nock/nock которая патчит низкоуровневый код и подменяет его фейком, который не делает никаких запросов. • С помощью ифов • Как развитие предыдущего пункта, с помощью полиморфизма Поговорим о последних двух. Мы легко могли бы расставить по коду проверки на окружение: if (process.env.NODE_ENV === ‘testing’) { // ничего не делаем } else { // реальный запрос } Однако, этот код ведет к двум проблемам. Во-первых вызов кода по условию скрывает возможные ошибки и делает код сложнее. Тут легко напортачить и получить работающий тест, но не работающий код. Во-вторых, представьте что у вас таких вызовов десятки, а то и сотни. Во что превратиться код? Выйти из этой ситуации можно с помощью применения полиморфизма. Для этого понадобится продублировать библиотеку octokit/rest.js но внутри, вместо реальных запросов, например, складывать данные в свойства объекта-библиотеки. Дальше, в отдельном файле пишем: let octokit; if (process.env.NODE_ENV === ‘testing’) { octokit = new OctokitFake(); } else { octokit = new Octokit(); } export octokit; Вуаля, импортируем файл где надо и используем его не думая ни про какую тестовую среду. Конечно при этом фейковый объект должен иметь возможность настраиваться снаружи, чтобы возвращать нужные данные в нужных условиях. В итоге мы получаем единообразный способ работы, с точки зрения приложения не существует никакого фейкового варианта либы. И если что-то меняется, то код приложения не меняется, изменения идут либо в либах, либо в этом отдельном файле. Это и есть полиморфизм подтипов (а объяснение последнего слова требует отдельного погружения в системы типов). p.s. Мастхев для чтения: https://guides.hexlet.io/ru/usefull-twitter-threads/#мифы-вокруг-ооп p.s.s. Требуется ли для полиморфизма подтипов наличие ооп?)
4 года назад
Размышления на тему полиморфизма
Привет, сегодня хочу поговорить про полиморфизм. Очень часто мне не хватает знаний по полиморфизму, я очень много уделил внимания этому вопросу , но до сих пор не уверен, что я до конца понимаю, что такое полиморфизм. Если вы знаете больше меня, обязательно напишите в комментариях в чём я ошибаюсь. Лично у меня нет уверенности, что я понимаю полиморфизм правильно. Всё дело в том, что полиморфизм — это сложная концепция и несмотря на то, что она формулируется очень просто, полиморфизм — это единственная реализация, множественное проведения, нюансов и реализаций там тьма...