Pull to refresh
7
0
Алексей @posledam

Руководитель разработки ПО

Send message

Не знаком к сожалению с синтаксисом D. Вижу тут выведение типа через auto, нет объекта как такового, это структура и компилятор явно вызывает известные на момент компиляции методы применительно к конкретной структуре известного типа, поэтому это работает на стеке. А давайте в общий базовый тип и вызовем метод, общий для всех объектов. Получится?

Пример на C#

object v = 42;
// вызов метода общего для всех-всех объектов
Console.WriteLine(v.ToString()); // выведет: 42

Компилятор "не знает" чей ToString() я вызываю, в рантайме вызывается метод, вычисляемый для конкретного экземпляра, через vtable.

Если я не пользуюсь самолётами, а езжу только поездами, можно ли считать, что в моём мире не существует самолётов?

Согласен, для формошлёпства и перекладывания из DTO в JSON, ООП не нужен, всё это от лукавого.

Ну например, если в общих чертах, то физический реальный договор это не тоже самое, что запись в БД. Под действием "подписать" может пониматься, проставить в записи о договоре отметку, что клиент собственноручно расписался на обоих бумажных экземплярах, и приложить фотографию. Т.е. мы говорит про изменение состояние записи в приложении, которое отвечает за какой-то аспект договорных отношений. Нет никакого "договора" в приложении. Есть запись, отражающая информационное состояние. И как показала моя практика (в различных проектных командах), это создаёт у разработчиков путаницу в определениях и сложному и совершенно не нужному дизайну классов. Там где нам надо было управлять состоянием, мы пытаемся вести себя как объекты реального мира, имитировать их. Это приводит к тому, что мы пытаемся контролировать на уровне класса, что контролировать там не нужно. Например, то же самое подписание, это с точки зрения бизнеса атомарное действия, либо подписал, либо нет, а с точки зрения операционного учёта, это транзакция с комплексом событий, оркестрация всего этого добра с подтверждениями и согласования между разными системами.

Ну далеко не только в Java же. Но везде есть свои, как говорится, приколы.

Про посылку сообщений объекту, ну это как бы тоже уровень абстракции. Чем строчка с вызовом метода у объекта по его ссылке не "отправка сообщения"? Если метод виртуальный, или вообще ЯП динамический, то в ответ также получим либо исключение, либо какой-нибудь undefined. Почему от абстракции посылки сообщений вообще везде ушли, наверное потому что это дико неудобно и сложно. Но также, не ручаюсь за именно такое объяснение. Однако имеем что имеем. На языках ООП, написаны горы полезных продуктов, в том числе те, которыми мы ежедневно пользуемся.

Стоит всё же кое что добавить к сказанному. Споры вокруг ООП чаще всего напоминают спор глухого со слепым. Огромный пласт работы, в которой задействованы программисты, это императивная логика, построенная на вызове методов, аннотациях и условиях, а классы это 99% контейнеры данных, контейнеры логики (контроллеры например), просто наборы методов для внедрения в DI. Нет тут никакой потребности в инкапсуляции, что и от кого скрывать? Это верхнеуровневая логика, прямо за ней уже находится пользователь, а не другой программист. Код призван решать конкретную бизнес задачу. Он типовой, похож на копипасту, но для бизнеса он крайне важен, так как закрывает таску в джире и открывает новую фичу. В этих условиях нужно понять разработчика, ему этот ООП как филькина грамота. Даёшь функциональщину! Вот это дело. Паттерн матчинги, лямбды, вот это всё нужно. А ваши ООП, это для дедов :)

Всё зависит от применения. Прикладная логика редко требует разработки классов. В основном это чистый императив и DTO. На этой почве чаще всего и звучат "ООП нинужен", когда основная часть работы это перекладывание данных из JSON в DTO и запросы в БД. При чём на плечах огромной кучи библиотек и платформы, с кучей классов под капотом. По той же логике можно с уверенностью сказать, что микроэлектронника не нужна. Да, у меня есть телефон, куча аппаратуры, я просто кнопки жму, зачем мне нужна ваша микроэлектронника? :)

Из своего опыта, когда начал разрабатывать библиотеки, свои расширения платформы, а потом и платформу, то все возможности ООП в такой разработке используются на 100%. И всё это очень нужно.

Утверждения про "побеждает", это примерно как щупать в слепую слона за хобот и утверждать, что хобот, это всё что нужно, хобот победил :)

Почему не норм? Это одна из эффективных форм познания. Сначала делаем глобальное обобщение, потом находим нарушения и несоответствия. Или надо сразу всё знать и говорить всегда только правильные вещи, и не дай бог ошибиться?

Нельзя стать экспертом, не пытаясь им стать. Или как должно быть. 30 лет программируешь, а потом просыпаешься и понимаешь, вот теперь кажется я и стал экспертом, теперь мне можно писать на хабр, и меня не заклюют и не заклеймят новичком :)

А если назначение было переосмыслено? Сколько вещей в мире было создано с одним назначением, а оказалось, что для этого оно подходит плохо, но зато хорошо подходит для другого? В разработке это наблюдается сплошь и рядом. А без холиворов не будет переосмысления, конечно имеются в виду аргументированные холиворы, а не набрасывание на вентилятор.

Вот самый банальный пример: "всё есть объект". Попытка глобального обобщения разбивается о суровую реальность. Когда "всё объект", технически это приводит к необходимости вот это "всё" держать в куче, чтобы была ссылка на объект. Но это не всегда рационально, местами крайне избыточно и сильно бьёт по производительности. И начинаются пляски, ну ладно "не всё объект" или по крайней мере не всегда, давайте вот отдельно выделим примитивы (Java), или объекты-структуры (ValueType, C#).

ООП не просто инструмент в вакууме. Это инструмент, который позволяет снизить сложность большого спектра задач. Но когда с помощью ООП начинают моделировать объекты реального мира, от банальных "кошек/собак" с их реализацией "мяукать/гавкать", до более сложных "договор" с методами "подписать", "принять", "отклонить" — то очень быстро приходит понимание, что ООП с этим справляется просто отвратительно и в целом для этого не подходит. Если конечно, находясь под эйфорией, не начинать подгонять молотком и зубилом любую задачу под ООП. Вот здесь самая суть проблемы, которую и превратили во зло.

В наборе тезисов есть недосказанность. Основное, классическое, и корневое заблуждение — это использование ООП, как описание объектов реального мира. ООП это поведение, которое имеет изменяемое или не изменяемое состояние, с возможностью инкапсуляции. Это не "кошки" и "собаки", которые могут "мяукать" или "гавкать". Вот такие примеры, призванные объяснить новичку сам принцип, превратились в примеры для подражания. А затем, спустя какое-то время, новичок сталкивается с тем, что ООП совершенно не подходит для описания объектов реального мира, и становится злом.

На голанг своя специфика, на прикладном уровне думать приходится только о структуре, логике. О производительности, потоках, и прочих узкоспециализированных концепциях задумываться приходиться редко. Благодаря маленьким масштабам, компактным сборкам, это всё бодро скейлится.

На пыхе, если оставаться в парадигме выполнил задачу => умер, то совсем не надо париться ни о чём. Только не надо сувать PHP между другими приложениями, в интеграционный слой. Там ему плохо, узко, тесно и ваще.

Так он и не задушил в описываемый период. А вот была JIT и ngen, который, генерил скомпиленные в *.ni.dll файлики. Да, компьютеры были медленными, именно поэтому в полный рост скрипты, расцвет PHP, всяких перлов и прочего.

Так разве это плохо? То, что мертво умереть не может. Но "хоронят" обычно вполне себе живые языки и платформы :)

  1. Весь бойлерплейт вынести в общий набор библиотек компании.

  2. Все инфраструктурные части, коннекторы, консюмеры, прослушиватели в общий набор библиотек проекта.

  3. Если сервис предоставляет АПИ, то он же обязан предоставить готовую для использования библиотеку для работы с собой (и выкинуть в нугет репозиторий)

Вуаля. Ни-ка-ких проблем, чтоб создать новый сервис и встроить его в инфраструктуру. В идеале, конечно, создание нового сервиса начинается с создания по шаблону и сразу переходом к написанию логики. Ой. ну прям как в монолите! :)

Основная сложность здесь, это развивать качественные соглашения и следовать им, вести разработку общих либ и.. думать о других разработчиках, думать наперёд. Когда вы думаете о других, или даже о себе (в будущем), то получается хорошая разработка.

Многие ошибочно считают, что у приложения есть только те пользователи, которых видит бизнес: клиенты, кастомеры, партнёры... Но ещё есть и другие пользователи, это обслуживание, сопровождение, мониторинг, администрирование — тоже пользователи, про которых обычно забывают. Разработчики являются пользователями своего же изделия с точки зрения разработки, его надо развивать, поддерживать. Если обо всём этом подумать, нет проблем ни с микро-сервисной архитектурой, ни с монолитной. И там и там есть свои плюсы в каждой конкретной ситуации.

Очень удобный подход, тоже к этому пришли.

Библиотеки и тулы это хорошо конечно. Но они не решение, а средство, при чём зачастую ограниченное. Ещё, как это ни печально, иногда некоторые средства перестают поддерживаться, устаревают.

Поговорим о решении.

Используем настройку Arrange по happy path, т.е. на идеальный сценарий, прям в конструкторе теста. Таким образом основной успешный тест будет самым простым, буквально в пару строк.

А вот все отклонения вносятся уже в настроенный идеальный сценарий, в код каждого теста. Добавляется ещё несколько строк для каждого отклонения.

Это позволяет всегда оценивать все тесты с учётом изменений в идеальном сценарии, отказаться от кучи бойлерплейта, просто вносим точечные мутации в Arrange и проверяем ровно то, что нам интересно.

Information

Rating
5,628-th
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Backend Developer, Руководитель отдела разработки
Lead
From 450,000 ₽
C#
.NET
Software development
Database
High-loaded systems
Designing application architecture
Creating project architecture
Design information systems
Monitoring