Ну ок, я определил такой интерфейс в случае с интерфейсом. И определил публичную функцию в случае без интерфейса. Но на мой взляд озвученные вами претензии одинаково применимы или не применимы в обоих случаях.
Ну или почему вы считаете что функцию я могу менять как хочу, а интерфейс нет? В чём разница?
Мне кажется, что мы друг друга не понимаем. В предыдущем комментарии, я как раз и пытался показать, что разницы, как это называть (просто публичная функция или интерфейс) никакой нет. И публичные функции тоже входят в понятие интерфейсов, как подмножество. А главная проблема начинается тогда, когда вы заранее пытаетесь определить и выявить все функции и структуры данных с которыми они работают в вашем приложении.
Но так как вы уже определили такой интерфейс (в глобальном смысле) взаимодействия с Foo
Имелось ввиду вашу публичную функцию, поэтому я написал интерфейс в глобальном смысле слова.
Недостаток имеет вариант, когда вы заранее решили, что вам нужен именно метод GetFooData, и что он должен принимать именно int dataId, хотя возможно вместе с id, во многих местах, вам будет нужен еще и String name и оптимальнее было бы сделать структуру данных содержащую id и name. Но так как вы уже определили такой интерфейс (в глобальном смысле) взаимодействия с Foo, то в остальных местах, где вам нужно еще и name, вы можете добавить дополнительные ненужные и неоптимальные функции, которые получают name. А то, что у этого сразу определен еще и ООП интерфейс уже вторично. Естественно с одним, двумя и тд классов, это не кажется большой проблемой, но мы же говорим о более крупных проектах, где их десятки и сотни, и они взаимодействуют друг с другом.
Ок, я полагаю, что путаница может возникать из за разных трактовок слова интерфейс. Мы вроде бы не трактуем слово интерфейс в узком ООП смысле. Об этом было написано выше.
Я бы с вами не согласился, интерфейс понятие более общее и существуют в отдельности от ООП. Как тогда по вашему работают все большие проекты написанные без использования данной парадигмы?
Под словом интерфейс предполагается совокупность методов и функций и тогда вопрос теряет смысл.
Это если у вас есть множество реализаций. И если они есть, то вам без интерфейса вообще по хорошему не обойтись. То есть на мой взгляд в таком случае необходимость интерфейса даже обсуждать глупо.
Еще раз, мною нигде не сказано, что интерфейсы не нужны, я не понимаю, почему вы продолжаете это утверждать. Я говорю, что их преждевременное введение без необходимости, часто создает проблемы по ходу дальнейшей разработки. Интерфейсы это всегда границы, так вот, если в начале разработки, эти границы были определены неправильно (что происходит часто, так как проект большой и сделать это правильно и оптимально до реализации практический невозможно), то хоть это может звучать контр-интуитивно, вам нужно убрать эти границы, посмотреть на код без них и провести новые, более оптимальные.
Во первых это уже зависит от IDE и тулинга в принципе. Различные анализаторы они тоже развиваются и на месте не стоят
Я сомневаюсь, что такие анализаторы существуют, которые могут находить более глобальные оптимизации автоматически. К тому же, понятие оптимизации, зависит от конкретной цели. У всего есть обратная сторона, и в одном случае изменение может считаться оптимизацией, а в другом нет.
А во вторых чем вам интерфейсы то в данном случае мешают? Вам же никто не запрещает и на конкретную реализацию смотреть. Это же не так что если интерфейс есть, то всё что за ним автоматом становится невидимым....
В теории да, но на практике очень сложно держать в голове множество реализаций и каждый раз заглядывая внутрь. Общая картина теряется.
С другой стороны создание и подержка интерфейсов практически "бесплатна" и не занимает время если у вас есть IDE с адекватным функционалом.
Да, и еще, что я заметил на своем опыте, что преждевременное введение интерфейсов и локальных оптимизаций(привет Кнуту), скрывает от тебя более глобальные оптимизации. И если взять и переписать решение "в лоб", без абстракций, то можно увидеть намного более удачные абстракции, чем те, что были прежде. А это IDE вам не поможет обнаружить.
Я думаю, что без конкретики мы далеко не уйдем. Так как тут не совсем понятен размер проекта, и что подразумевается под модулем. Возможно если вы работаете над готовым проектом, с уже имеющимися интерфейсами и дополняете ее модулями, то в вашем случае, это удобный вариант. Я не собираюсь навязывать свою точку зрения, я ее озвучиваю и признаю, что в отдельных ситуациях такой подход может работать, но вводить интерфейсы без необходимости при начальной разработке, это плохое решение.
Я признаю, что моя формулировка может трактоваться по разному, но я нигде не писал, что я против интерфейсов или то, что их не нужно использовать, или без них можно вообще обойтись. Моя критика была направленная на конкретный догматический принцип написания кода, который постулирует, что нужно пытаться придумывать/проектировать интерфейсы без предварительной реализации функционала. Это не относится к более-менее большим модулям программы, над которыми могут работать несколько человек или команд. В этом случае вам по любому придется договаривать и вводить интерфейсы между этими модулями, хоть даже временные. Я говорю о применении данного принципа при написании функций, классов и структур данных, когда в преждевременном введении интерфейсов нет никакой необходимости.
Это ситуации вынужденного введения интерфейсов. Они есть в каждом проекте, но количество подобных интерфейсов всегда невелико (зависит от размера проекта).
Здравствуйте, в первую очередь, я хочу заметить (как уже делал это в другом комментарии), что я нигде не говорил, что интерфейсы, это плохо. Я говорил, что принцип программирования, в котором предполагается проектирование интерфейсов между всеми частями программы до реализации самого функционала, в большинстве случаев ошибочен и приводит к плохой и неоптимальной архитектуре.
Интерфейсы и абстракции, это несомненно важные вещи. Вопрос в том, насколько они удобны и оптимальны, а также, каким способом они достигаются.
Мне тяжело сказать что-то конкретное по поводу вашего примера, так как я не видел ни конкретной задачи и данных, ни вашего кода. Возможно у вас нет никаких проблем.
Просто не надо возводить эвристические принципы в абсолют.
Абсолютно согласен.
Неудачные интерфейсы можно и нужно переписывать. Но из этого вовсе не следует, что интерфейсы вообще не нужны.
Я нигде не утверждал, что интерфейсы не нужны. Я утверждал, что принцип программирования - "интерфейсы, до реализации" в большинстве случаев ошибочен, хотя конечно бывают ситуации, когда он помогает.
Мотивацией к статье было то, что я слишком часто слышу, как люди пропагандируют разные сомнительные принципы разработки (которые на первый взгляд действительно кажутся очень полезными и логичными), как единственно правильные, best practices и тп.
Программирование на уровне интерфейсов -- огромное преимущество ООП, без этого сегодня ни один большой проект не обойдётся
Я бы с вами не согласился, интерфейс понятие более общее и существуют в отдельности от ООП. Как тогда по вашему работают все большие проекты написанные без использования данной парадигмы?
Если совсем кратко, то я бы еще охарактеризовал так:
Подобный принцип программирования заставляет на раннем этапе вводить неоптимальные интерфейсы/абстракции, вокруг которых пишется остальной код, который их использует, что в большинстве случаев приводит к лишним проблемам и постоянным корректировкам этих интерфейсов и сопутствующего кода по мере дальнейшей разработки. Или, что еще хуже, оставления этих первоначальных интерфейсов без изменений.
Ну скажем так, в первую очередь защищать практически любую позицию с претензией на абсолютную истину я считаю бесперспективным, так как любой контрпример нивелирует все ваши усилия. К данной статье я и сам могу привести контрпример :) Но применительно к большинству ситуаций, я готов отстаивать свою позицию, так как она основана на личном опыте, а не просто взята из учебника или статьи.
То есть на любом этапе важная часть проектирования - попытаться выделять сущности, скрывающие детали реализации - так их использование будет проще в дальнейшем.
Как раз в этом я и вижу проблему, так как правильно и оптимально выделить сущности до конкретной реализации, очень сложно. Так как приходится пытаться учитывать все различные варианты их взаимодействия и использования. Когда у тебя уже есть реализация, то провести границы, вывести из нее абстракции и интерфейсы становится намного проще
Мне кажется, что мы друг друга не понимаем. В предыдущем комментарии, я как раз и пытался показать, что разницы, как это называть (просто публичная функция или интерфейс) никакой нет. И публичные функции тоже входят в понятие интерфейсов, как подмножество. А главная проблема начинается тогда, когда вы заранее пытаетесь определить и выявить все функции и структуры данных с которыми они работают в вашем приложении.
Имелось ввиду вашу публичную функцию, поэтому я написал интерфейс в глобальном смысле слова.
Недостаток имеет вариант, когда вы заранее решили, что вам нужен именно метод GetFooData, и что он должен принимать именно int dataId, хотя возможно вместе с id, во многих местах, вам будет нужен еще и String name и оптимальнее было бы сделать структуру данных содержащую id и name. Но так как вы уже определили такой интерфейс (в глобальном смысле) взаимодействия с Foo, то в остальных местах, где вам нужно еще и name, вы можете добавить дополнительные ненужные и неоптимальные функции, которые получают name. А то, что у этого сразу определен еще и ООП интерфейс уже вторично. Естественно с одним, двумя и тд классов, это не кажется большой проблемой, но мы же говорим о более крупных проектах, где их десятки и сотни, и они взаимодействуют друг с другом.
Ок, я полагаю, что путаница может возникать из за разных трактовок слова интерфейс. Мы вроде бы не трактуем слово интерфейс в узком ООП смысле. Об этом было написано выше.
Под словом интерфейс предполагается совокупность методов и функций и тогда вопрос теряет смысл.
Еще раз, мною нигде не сказано, что интерфейсы не нужны, я не понимаю, почему вы продолжаете это утверждать. Я говорю, что их преждевременное введение без необходимости, часто создает проблемы по ходу дальнейшей разработки. Интерфейсы это всегда границы, так вот, если в начале разработки, эти границы были определены неправильно (что происходит часто, так как проект большой и сделать это правильно и оптимально до реализации практический невозможно), то хоть это может звучать контр-интуитивно, вам нужно убрать эти границы, посмотреть на код без них и провести новые, более оптимальные.
Я сомневаюсь, что такие анализаторы существуют, которые могут находить более глобальные оптимизации автоматически. К тому же, понятие оптимизации, зависит от конкретной цели. У всего есть обратная сторона, и в одном случае изменение может считаться оптимизацией, а в другом нет.
В теории да, но на практике очень сложно держать в голове множество реализаций и каждый раз заглядывая внутрь. Общая картина теряется.
Да, и еще, что я заметил на своем опыте, что преждевременное введение интерфейсов и локальных оптимизаций(привет Кнуту), скрывает от тебя более глобальные оптимизации. И если взять и переписать решение "в лоб", без абстракций, то можно увидеть намного более удачные абстракции, чем те, что были прежде. А это IDE вам не поможет обнаружить.
Я думаю, что без конкретики мы далеко не уйдем. Так как тут не совсем понятен размер проекта, и что подразумевается под модулем. Возможно если вы работаете над готовым проектом, с уже имеющимися интерфейсами и дополняете ее модулями, то в вашем случае, это удобный вариант. Я не собираюсь навязывать свою точку зрения, я ее озвучиваю и признаю, что в отдельных ситуациях такой подход может работать, но вводить интерфейсы без необходимости при начальной разработке, это плохое решение.
Я признаю, что моя формулировка может трактоваться по разному, но я нигде не писал, что я против интерфейсов или то, что их не нужно использовать, или без них можно вообще обойтись. Моя критика была направленная на конкретный догматический принцип написания кода, который постулирует, что нужно пытаться придумывать/проектировать интерфейсы без предварительной реализации функционала. Это не относится к более-менее большим модулям программы, над которыми могут работать несколько человек или команд. В этом случае вам по любому придется договаривать и вводить интерфейсы между этими модулями, хоть даже временные. Я говорю о применении данного принципа при написании функций, классов и структур данных, когда в преждевременном введении интерфейсов нет никакой необходимости.
Это ситуации вынужденного введения интерфейсов. Они есть в каждом проекте, но количество подобных интерфейсов всегда невелико (зависит от размера проекта).
Здравствуйте, в первую очередь, я хочу заметить (как уже делал это в другом комментарии), что я нигде не говорил, что интерфейсы, это плохо. Я говорил, что принцип программирования, в котором предполагается проектирование интерфейсов между всеми частями программы до реализации самого функционала, в большинстве случаев ошибочен и приводит к плохой и неоптимальной архитектуре.
Интерфейсы и абстракции, это несомненно важные вещи. Вопрос в том, насколько они удобны и оптимальны, а также, каким способом они достигаются.
Мне тяжело сказать что-то конкретное по поводу вашего примера, так как я не видел ни конкретной задачи и данных, ни вашего кода. Возможно у вас нет никаких проблем.
Согласен на счет отсутствия примеров, добавил комментарий в конце статьи.
Согласен, я добавил подробный комментарий в конце статьи.
Это хорошо работает с публичными интерфейсами и api, но всю внутреннюю архитектуру, так не построишь.
Абсолютно согласен.
Я нигде не утверждал, что интерфейсы не нужны. Я утверждал, что принцип программирования - "интерфейсы, до реализации" в большинстве случаев ошибочен, хотя конечно бывают ситуации, когда он помогает.
Мотивацией к статье было то, что я слишком часто слышу, как люди пропагандируют разные сомнительные принципы разработки (которые на первый взгляд действительно кажутся очень полезными и логичными), как единственно правильные, best practices и тп.
Я бы с вами не согласился, интерфейс понятие более общее и существуют в отдельности от ООП. Как тогда по вашему работают все большие проекты написанные без использования данной парадигмы?
Если совсем кратко, то я бы еще охарактеризовал так:
Подобный принцип программирования заставляет на раннем этапе вводить неоптимальные интерфейсы/абстракции, вокруг которых пишется остальной код, который их использует, что в большинстве случаев приводит к лишним проблемам и постоянным корректировкам этих интерфейсов и сопутствующего кода по мере дальнейшей разработки. Или, что еще хуже, оставления этих первоначальных интерфейсов без изменений.
Ок, может быть в будущем напишу более подробно и с примерами, так как их у меня хватает.
Ну скажем так, в первую очередь защищать практически любую позицию с претензией на абсолютную истину я считаю бесперспективным, так как любой контрпример нивелирует все ваши усилия. К данной статье я и сам могу привести контрпример :) Но применительно к большинству ситуаций, я готов отстаивать свою позицию, так как она основана на личном опыте, а не просто взята из учебника или статьи.
Не буду спорить, для этого в начале статьи есть дисклеймер :)
Но все эти отдельные классы не живут в вакууме, а взаимодействуют друг с другом внутри вашего проекта по средствам этих интерфейсов .
Как раз в этом я и вижу проблему, так как правильно и оптимально выделить сущности до конкретной реализации, очень сложно. Так как приходится пытаться учитывать все различные варианты их взаимодействия и использования. Когда у тебя уже есть реализация, то провести границы, вывести из нее абстракции и интерфейсы становится намного проще