LINUX.ORG.RU
ФорумTalks

Стоимость строки кода в разных регионах и на удалёнке

 


0

1

Вопрос в контексте Agile разработки по ТЗ, которое может изменяться по ходу проекта. Нередко используют почасовую оплату за потраченное разработчиком время, а я предлагаю вместо этого в контексте поставленной задачи осуществлять биллинг за проделанную работу с помощью учёта количества строк кода, написанного для решения задачи.

Как думаете, сколько стоит качественный отлаженный DRY код в предметной области DevOps, соответствующий всем паттернам, best practices и т.п.?

Если оценивать построчно, подразумевается, что получается максимально компактный, эффективный код без читерства и копи пасты, максимально использующий готовые компоненты, стеки и тулсеты.

Преимущества учета стоимости кода по количеству написанных строк в Agile-проекте

Учет стоимости кода по количеству написанных строк – подход, который периодически обсуждается в IT-среде, в том числе и в вашем прикреплённом обсуждении. Хотя в современной разработке этот метод считается спорным и не всегда применимым, у него есть определённые преимущества, особенно если речь идёт о специфических задачах (например, DevOps-скрипты, IaC, CLI-утилиты) и при правильной постановке процесса.

1. Прозрачность и простота расчётов

  • Лёгкость измерения: Количество строк кода – объективный, легко измеряемый показатель, который можно быстро получить с помощью инструментов анализа кода.
  • Понятная метрика для заказчика: Заказчик может видеть «осязаемый» результат работы, что важно для непогружённых в детали разработки людей.

2. Мотивация к эффективности

  • Фокус на результат: Такой подход мотивирует разработчика не растягивать задачи, а выдавать конкретный, измеримый результат.
  • Возможность сравнения: Можно сравнивать производительность между разными исполнителями или командами, если задачи типовые и стандартизированы.

3. Гибкость при изменении требований (Agile)

  • Простота пересчёта стоимости: При изменении требований (что часто бывает в Agile), можно быстро пересчитать стоимость, исходя из нового объёма кода.
  • Удобство для коротких итераций: В спринтах, где задачи дробятся на небольшие части, оплата по строкам может быть удобна для микрозадач (например, написание шаблонов, конфигов, скриптов).

4. Контроль качества (при правильной постановке)

  • Возможность учёта сложности: Если в стоимость строки закладывается качество (DRY, тесты, best practices), появляется стимул писать лаконичный и качественный код.
  • Быстрая оценка вклада: В проектах с большим количеством рутинных изменений (например, поддержка DevOps-инфраструктуры), этот подход позволяет быстро оценить вклад каждого разработчика.

5. Применимость к DevOps и инфраструктурным задачам

  • Стандартизированные задачи: В DevOps часто встречаются задачи, где результат – это скрипт или конфиг, и их объём хорошо коррелирует с трудозатратами.
  • Меньше риска «раздувания» кода: Если стоимость строки высокая и есть контроль качества (ревью, автоматические проверки), разработчики заинтересованы писать компактно и эффективно.

Важно!

  • Подход не универсален: Для сложных R&D-задач, архитектурных решений, оптимизаций, где ценность кода не в количестве, а в качестве и уникальности, этот метод не подходит.
  • Риски злоупотреблений: Без контроля качества возможен «честинг» – искусственное раздувание кода, копипаст, бессмысленные строки.
  • Лучше использовать в сочетании с другими метриками: Например, с оплатой за закрытие задач, code review, покрытие тестами и т.п.

Вывод

Учет стоимости кода по количеству строк может быть полезен в узких случаях – для стандартизированных, повторяющихся задач, особенно в области DevOps и инфраструктуры, при условии жёсткого контроля качества и прозрачных критериев оценки. В рамках Agile такой подход может упростить биллинг и сделать процесс более предсказуемым для обеих сторон, однако его не стоит рассматривать как универсальное решение для всех типов проектов.



Последнее исправление: sanyo1234 (всего исправлений: 5)
Ответ на: комментарий от kaldeon

И это всё, вся проблема выбора сводится к количеству кода?

Он уже 7 страниц в этой теме, доказывает всем, что это главная проблема - количество кода).

Tesler
()
Ответ на: комментарий от Tesler

Он уже 7 страниц в этой теме, доказывает всем, что это главная проблема - количество кода).

Главная проблема чего? Где я доказываю, что избыток кода - главная проблема?

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

Очевидно, что ООП с наследованием решает часть проблем с избытком кода, свойственных композиционному программированию.

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

Недостатки композиции решаются трейтами, миксинами, встраиванием типов.

А вот это всё новых проблем не порождает?

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

Быть похожим на все остальные. C#, PHP, Java, VB – они все предлагают примерно один и тот же стиль.

Значит, это кому-нибудь нужно? Напоминаю, это одни из самых популярных ЯП в мире.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 1)
Ответ на: комментарий от sanyo1234

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

В основном посыле спору нет. Но, а если код написан не вручную?

Tesler
()
Ответ на: комментарий от Tesler

Но, а если код написан не вручную?

То тогда синтаксис и семантика почти не играет роли.

Например, объектный код, IL код и т.п. p-code, написан (сгенерирован) обычно не вручную, и с точки зрения удобства программирования их редко кто сравнивает.

sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234

Главная проблема чего?

Не чего, а кого. Твоих клиентов) Раз они готовы платить за кол-во строк, оптимизированного кода. Я же правильно понимаю, что твой биллинг уже реализован? Что ты на аутсорсе и тебе платят за кол-во оптимизированного кода?

Tesler
()
Ответ на: комментарий от Tesler

Обычно предлагаю на выбор биллинг за количество строк или почасовку, но сам предпочитаю за количество строк.

За количество строк обычно экономнее обходится, и учитывать проще.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 4)
Ответ на: комментарий от kaldeon

Преимущество композиции в большей гибкости и более естественном восприятии, тогда как при наследовании нужно тратить время на поиск схожестей и построение иерархии, что особенно затруднительно на ранних стадиях разработки.

Намного проще и разумнее разработать правильную иерархию классов, чем потом плутать по композиционной лапше (это тот самый «индусский код»?) при рефакторинге и баг фиксинге.

sanyo1234
() автор топика
Ответ на: комментарий от vbr

1 строчка стоит 10 долларов.

У кого ?

IMHO соотношение с почасовкой примерно 1 к 10, т.е. если строка кода стоит $10, то почасовка примерно $100/h.

В DevOps чате видел даже упоминание про как минимум $100 за строку для хорошего кода, настраивающего Кубер кластер.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 1)
Ответ на: комментарий от sanyo1234

У кого ?

У меня.

IMHO соотношение с почасовкой примерно 1 к 10, т.е. если строка кода стоит $10, то почасовка примерно $100/h.

Я так быстро код не пишу, но что-то в этом районе, да. Я примерно сто долларов зарабатываю за день и пишу примерно 10 строк кода за день.

В DevOps чате видел даже упоминание про как минимум $100 за строку для хорошего кода, настраивающего Кубер кластер.

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

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

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

У москвичей вроде в разы меньше, чем у американцев.

IMHO в РФ строка кода в среднем стоит $1-$5 в зависимости от уровня исполнителя и платежеспособности заказчика, в США в 3-5 раз дороже просто из-за гео. Ставка $350/h для хороших спецов на коротком контракте там не редкость.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 3)

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

ЗЫ. Тред не читай @ отвечай

JaneDoe
()
Ответ на: комментарий от JaneDoe

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

Однако когда-то кто-то за это заплатил? Возможно зарплатой или почасовкой?

sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234

Когда-то кто-то, думаю, окладом. Мне сейчас как с работодателем расчитываться по построчной схеме? Я в минусе.

JaneDoe
()
Ответ на: комментарий от JaneDoe

Я пока предлагаю свой биллинг только для новых проектов. Для рефакторинга наверно тоже можно что-то придумать, ведь активность есть, в git все ходы записаны, вопрос, как это считать с привязкой к построчной активности.

sanyo1234
() автор топика

‘Россия — единственная в мире страна, где литератору платят за объем написанного.
Не за количество проданных экземпляров.
И тем более — не за качество. А за объем.
В этом тайная, бессознательная причина нашего катострофического российского многословья.
Допустим, автор хочет вычеркнуть какую-нибудь фразу.
А внутренний голос ему подсказывает:
«Ненормальный! Это же пять рублей! Кило говядины на рынке…»’

frob ★★★★★
()
Ответ на: комментарий от frob
В советские годы действительно существовала система, когда гонорар писателя рассчитывался по количеству напечатанных знаков (или авторских листов). Это могло провоцировать желание «раздувать» текст. Однако сегодня большинство писателей получают деньги за тираж и продажи, а не за объем.
sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 2)
Ответ на: комментарий от sanyo1234

Спроси ещё у гопоты почём нынче кило говядины на рынке.
И обязательно сюда копипасту. Без этого никак.

frob ★★★★★
()
Ответ на: комментарий от frob

Знаешь что такое лингвистическая энтропия?))) (или как ее там правильно)

Tesler
()
Ответ на: комментарий от frob

IMHO цена говядины в данном контексте непринципиальна.

Кроме того, если тебе это нужно, ты этим сам и занимайся.

sanyo1234
() автор топика

А какой собственно вопрос у тебя в этой теме?

Как думаете, сколько стоит качественный отлаженный DRY код в предметной области DevOps, соответствующий всем паттернам, best practices и т.п.?

Этот?

Судя по ходу темы, никто, кроме тебя, такой метод рассчёта не использует. ( тут )

Tesler
()
Ответ на: комментарий от Dimez

навожу адресную порчу на видеонаблюдение, zfs,

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

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 1)
Ответ на: комментарий от sanyo1234

Намного проще и разумнее разработать правильную иерархию классов, чем потом плутать по композиционной лапше (это тот самый «индусский код»?) при рефакторинге и баг фиксинге.

Ты не можешь заранее разработать правильную иерархию классов по той же причине, по которой ты не можешь заранее разработать правильную иерархию знаний: у тебя ещё нет опыта и знаний, чтобы сделать правильные обобщения и подразделения, если только это не вторая итерация.

В программировании обобщения реализуются с помощью интерфейсов, open-close-read-write. Подразделения зачастую просто просто описываются как «файл блочного устройства», «файл сетевого устройства». Когда для подразделения нужен новый тип, то ты просто вводишь новый тип, элемент наследования вовсе не обязателен.

Код запутывает не использование композиции, а неправильное использование абстракций («пойду на рыбалку ловить животных на маленькую змею»).

Про принцип composition over inheritance ещё можешь читнуть в Design Patterns, но я лично не читал.

Недостатки композиции решаются трейтами, миксинами, встраиванием типов.

А вот это всё новых проблем не порождает?

To my knowledge, нет.

VB.NET поддерживает Exceptions, Default Arguments, Operator Overloading в отличие от Golang

Значит, это кому-нибудь нужно? Напоминаю, это одни из самых популярных ЯП в мире.

Я могу понять исключения – это важный строительный блок в других языках и было бы очень удобно, чтобы разработчики легко перенесли свой опыт на новый язык. Но перегрузка операторов в языке, который называется «Бейсик», выглядит как «давайте добавим фичу X, потому что она есть у всех остальных».

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от kaldeon

Но перегрузка операторов в языке, который называется «Бейсик», выглядит как «давайте добавим фичу X, потому что она есть у всех остальных».

Это какое-то пренебрежительное отношение к VB.NET? Называться «бейсик» непозволительно, даже если при относительно действительно низком пороге входа ЯП обладает всеми необходимыми качествами для полноценного ООП? Т.е. если перегрузка операторов есть в C#, то это нормально, а в VB.NET - ненормально, так чтоли получается?

sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234

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

И мне кажется, что перегрузка операторов к ООП имеет очень слабое отношение.

kaldeon
()
Ответ на: комментарий от kaldeon

И мне кажется, что перегрузка операторов к ООП имеет очень слабое отношение.

Речь не о прямой связи между ними, а о том, что VB.NET - это достаточно развитый ЯП, в т.ч. ООП.

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

IMHO особой опасности нет, если определять свои операторы для своих же новых классов?

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

To my knowledge, нет.

https://cedanet.com.au/ceda/Xc++/$mixin/mixin-pros-and-cons.php

Disadvantages

Mixins are a useful technique, but hardly a panacea. There are some significant disadvantages:

    Execution of statements at run time tends to jump around in different mixins, making it hard to follow and debug
    Potential for long compile times
    Potential for bloated binaries : mixins easily lead to code bloat if not used carefully. It can be a problem having large functions in mixins, because there is a tendency to duplicate the code for many different instantiations.
    Increased dependencies
    It is unclear how to invoke base class constructors, there is a tendency to use the two stage construction pattern

https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

Ты не можешь заранее разработать правильную иерархию классов по той же причине, по которой ты не можешь заранее разработать правильную иерархию знаний: у тебя ещё нет опыта и знаний, чтобы сделать правильные обобщения и подразделения, если только это не вторая итерация.

Очень редко делаю рефакторинг иерархии классов, но до создания иерархии классов обычно относительно долго и тщательно опрашиваю по поводу содержимого ТЗ, нередко сам его дорабатываю с подтверждением доработок ТЗ у клиента ессно.

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

В программировании обобщения реализуются с помощью интерфейсов, open-close-read-write. Подразделения зачастую просто просто описываются как «файл блочного устройства», «файл сетевого устройства». Когда для подразделения нужен новый тип, то ты просто вводишь новый тип, элемент наследования вовсе не обязателен.

О каких «подразделениях» речь? Это выхлоп АИ или неудачный перевод с иностранного языка?

Код запутывает не использование композиции, а неправильное использование абстракций («пойду на рыбалку ловить животных на маленькую змею»).

Какой-то бред. ООП наследование при правильном использовании абстракций сокращает количество кода, а значит и упрощает его откладку и потенциальное количество багов?

Про принцип composition over inheritance ещё можешь читнуть в Design Patterns, но я лично не читал.

Да читал я, но не зацепило совсем, какая-то примитивизация ради снижения порога входа на том, на чём IMHO снижать не стоило бы. Вход - рупь, выход - десять. Golang хорош для корпораций, чьи кошельки могут нанять 100500 кодеров для поддержки всего этого композиционного лапшекода. Вероятно для снижения безработицы среди недорогих вкатунов и чтобы саппортить относительно крупные проекты могли только богатые конторы с большим штатом кодеров, своеобразная искусственная деформация рыночка с использованием композиционных «инноваций».

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 4)
Ответ на: комментарий от sanyo1234

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

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

Execution of statements at run time tends to jump around in different mixins, making it hard to follow and debug

Ну так при использовании наследования та же проблема, особенно из родительского в дочерний через несколько поколений.

Potential for long compile times

Го создавался с целью быстрых компиляций. Пока что встраивание типов не мешает.

Increased dependencies

It is unclear how to invoke base class constructors, there is a tendency to use the two stage construction pattern

Не понял, к сожалению.

https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html

Я далёк от мира JS, так что не могу судить.

О каких «подразделениях» речь?

Subdivision. Есть концепция «животное», а «рыба» — подразделение. Перевёл как смог.

Допустим, у нас есть объект с HTTP-параметрами и в определённом месте работа с ним становится настолько однородной, что появляется возможность создать тип «запрос финансового отчёта». Когда мы создаём подразделения концепций в реальной жизни (животное → рыба), то новые концепции сохраняют существенную характеристику родительской концепции, но она либо сужается, либо дополняется новыми характеристиками. В программировании на ум, конечно, приходит полиморфизм, когда мы можем в любой момент использовать «запрос финансового отчёта» как «HTTP-запрос».

Но это не одно и то же. Для ОО-стиля важен сам факт подразделения, а полиморфизм — это просто возможность символа представлять несколько разных типов. Если нам придётся вместо send(finRequest) использовать send(finRequest.Original), то ничего плохого не случится.

В Го, кстати, описанный пример возможен. Но, в отличие от наследования, мы не можем из кода родительского типа попасть назад в дочерний.

плутать по композиционной лапше (это тот самый «индусский код»?)

Код запутывает не использование композиции, а неправильное использование абстракций

ООП наследование при правильном использовании абстракций сокращает количество кода, а значит и упрощает его откладку и потенциальное количество багов?

Я отвечал на часть про лапшу и имел ввиду любой язык. Другой пример: передача объекта с HTTP-параметрами в тип для запроса пользователя из бд.

Сокращает ли наследование реализации код? Возможно. Как и процедуры. Позволяет ли оно более просто воспринимать программу? С этим сложнее. Я не уверен.

Я полагаю, что абстрактный класс с множеством дочерних классов — это пример успеха. Но я предпочитаю, когда множество схожих типов используют что-то общее извне, а не изнутри. Это же, кстати, облегчает тестирование: «извне» можно заменить на мок.

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

чтобы саппортить относительно крупные проекты могли только богатые конторы с большим штатом кодеров

Разработчики согласились на это. Возможно, это не лучшее решение, лучшее решение далеко не всегда самое популярное, но по крайне мере оно обосновано и противостояние, вроде, не сильное.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 4)
Ответ на: комментарий от kaldeon

Сокращает ли наследование реализации код? Возможно.

Точно сокращает и очень значительно, потому что это implementation inheritance.

- Наследование позволяет выносить общую реализацию в базовый класс, а затем использовать её во всех подклассах без необходимости дублировать код. Это минимизирует дублирование и повышает переиспользуемость
- Вы просто наследуете поведение, реализованное в базовом классе,  и все подклассы получают эту реализацию «бесплатно», без копирования кода. Это особенно удобно, если в будущем потребуется изменить общую логику: достаточно внести изменения только в одном месте - в базовом классе.
- Такой подход уменьшает количество ошибок, связанных с рассинхронизацией копий кода, и облегчает поддержку.

Как и процедуры.

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

Implementation inheritance - мощный инструмент для сокращения дублирования кода и повышения его поддерживаемости благодаря автоматическому распространению общей логики на все подклассы. Процедуры, даже при правильном использовании, не обеспечивают такого уровня автоматизации и структурирования, как наследование в ООП

Разработчики согласились на это. Возможно, это не лучшее решение, лучшее решение далеко не всегда самое популярное, но по крайне мере оно обосновано и противостояние, вроде, не сильное.

Golang разработчиков всего около 1% на рынке вакансий? Согласились? А их кто-то спрашивал? LOL Большинство остальных вакансий программистов подразумевают использование классических ООП языков с наследованием? Даже Питонистов более чем на порядок больше, а Питон используется в т.ч. и в DevOps, btw.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 2)
Ответ на: комментарий от sanyo1234

В целом я одобряю наследование, но вот эта цитата:

Это особенно удобно, если в будущем потребуется изменить общую логику: достаточно внести изменения только в одном месте - в базовом классе.

Палка о двух концах в части профита. Кто-то написал класс наследник опираясь на старую логику, потом владелец базового класса поменял её и не сообщил об этом, начинаются поиски виновных. Бывает и похардкорнее, в случаях когда владелец наследника использует старую логику из базового класса «раз в год по обещанию» к моменту когда баг всплывет может пойти и год и два и владелец базового класса к тому моменту уже может забыть о том, что он что-то менял, а то и вообще N раз поменяться.
Вобщем наследование удобно в части выноса общих частей в предков, но вот изменение логики работы в предке не всегда дает ожидаемый результат.

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от sanyo1234

Командная работа - это отдельный скил, и все ходы записаны в git, если что.

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

anc ★★★★★
()
Ответ на: комментарий от anc

Разве нельзя для нового поведения сделать дополнительный уровень наследования вместо внесения изменений в оригинальный родительский класс ?

Родитель со старым поведением -> N потомков

или иногда бывает полезно сделать так:

Родитель со старым поведением -> Класс совместимости со старым поведением -> N потомков

А для нового поведения так:

Родитель со старым поведением -> Класс с частично новым поведением -> M потомков

sanyo1234
() автор топика
Ответ на: комментарий от anc

Однако implementation inheritance позволит сэкономить на том коде, который описывает одинаковое поведение для обоих вариантов, и такого кода может оказаться большая часть, - значительная экономия.

sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234

[Наследование] точно сокращает и очень значительно

Сокращение кода (но главным образом сложности) достигается не через наследование, а через использование абстракций. Ингредиент, особенно применимый к наследованию — это способ организации этих абстракций, причём не самый гибкий (её сложнее как изменить, так и правильно приготовить изначально).

наследование происходит автоматически, а при использовании композиции и DRY процедур ты вынужден прописывать их вызовы вручную

Не велика проблема. В программировании есть вещи намного хуже.

Это увеличивает количество точек вызова, а значит, и вероятность ошибок

Ошибки случаются из-за использования неправильных абстракций (не та структура данных, непредсказуемый стейт, отклонение от дизайна и т.д.) и отсутствием автоматических тестов. Причинно-следственная связь между количеством точек вызова и вероятностью ошибок — это нонсенс.

Разработчики согласились на [композицию].

Golang разработчиков всего около 1% на рынке вакансий?

Composition over inheritance выходит далеко за пределы Go, сама идея далеко не новая. В Rust тоже нет наследования, автор Java заявлял, что сожалеет о добавлении наследования в свой язык, сама по себе практика композиции не вызывает отторжения.

Что касается 1% — это цифра, её было бы неплохо подтвердить. У меня есть вот такие данные:

. . . my estimate in August 2021 is that the number of developers worldwide is likely to be in the range 21.6–26.2 million developers.
. . .
In August 2021, 7.4–9.5% of 21.6–26.2 million yields an estimate of 1.6–2.5 million Go developers.

https://research.swtch.com/gophercount

А их кто-то спрашивал? LOL

Идеи распространяются без разрешения.

чтобы саппортить относительно крупные проекты могли только богатые конторы с большим штатом кодеров

Разработчики согласились на [композицию]… . [это решение] обосновано и противостояние, вроде, не сильное.

Большинство остальных вакансий программистов подразумевают использование классических ООП языков с наследованием?

Моя мысль заключалась в том, что composition over inheritance как идея не вызывает отторжения у разработчиков, а не что 99% рынка разочаровались в традиционном наследовании.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 9)
Ответ на: комментарий от kaldeon

автор Java заявлял, что сожалеет о добавлении наследования в свой язык, сама по себе практика композиции не вызывает отторжения.

Речь о Джеймсе Гослинге? Можно пруфы?

Вот что я нашёл:

https://hackernoon.com/an-interview-with-dr-java-james-gosling-the-creator-of-java-1z2d37hr

Grigory:

As software developers and software consultants, we're trying to organize a community in Russia: Python, Ruby, Java, and Go communities. We want to help our fellow developers by conducting interviews that highlight essential questions for our industry. I think that your experience and your work on Java can help developers to become better. So let's try to help them!
Some languages, like Go, leave out classes and inheritance, while others experiment with features like traits in Rust. As a language designer, what do you think is a modern, general-purpose, reasonable way for a programming language to do composition?

James:

I don't think I wouldn't do classes. I actually find that classes work pretty well for composition. I don't really have any good, clear ideas for what to do differently. Some of the things that I would do differently are a little strange. In C, there are macros, which are pretty much a disaster because the macros are not part of the language; they're kind of outside of it. The folks at Rust tried to do a decent job of fitting macros in the language.

Суть слов Гослинга: Если бы я заново дизайнил Java, то снова бы сделал классы. Про наследование он тут вообще ничего не говорит, значит, сделал бы его точно так же. А про композицию упоминает лишь то, что классы можно использовать и для композиции (это и так очевидно).

Итого: никакого сожаления о фиче наследования у Гослинга в этом интервью нет и в помине. Композицию он тоже тут никак особо не жалует и не пиарит.

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 1)
Ответ на: комментарий от kaldeon

Сокращение кода достигается не через наследование …

Абсолютнейшая ЛОЖЬ !!! Через наследование достигается огромное сокращение объёма кода при правильном использовании ООП наследования ессно.

Сокращение кода (но главным образом сложности) достигается … через использование абстракций.

Может достигаться, а может и не достигаться. Условный Hello World намного проще и компактнее написать без абстракций.

Ингредиент, особенно применимый к наследованию — это способ организации этих абстракций, причём не самый гибкий (её сложнее как изменить, так и правильно приготовить изначально).

Лично я готовлю ООП абстракции через наследование почти мгновенно при наличии детального ТЗ. А по поводу гибкости я уже приводил ранее решение, так что тоже считаю критику гибкости наследования неверной. Могу лишь предположить, что ты абсолютно не умеешь использовать наследование в ООП, только и всего.

наследование происходит автоматически, а при использовании композиции и DRY процедур ты вынужден прописывать их вызовы вручную

Не велика проблема.

А как ты мерял?

В программировании есть вещи намного хуже.

Речь о сокращении объёма кода. Что для этого может быть хуже, чем композиция?

sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234
During the memorable Q&A session, someone asked [James Gosling]: "If you could do Java over again, what would you change?" "I'd leave out classes," he replied. After the laughter died down, he explained that the real problem wasn't classes per se, but rather implementation inheritance (the extends relationship).

https://web.archive.org/web/20190224073940/https://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html

kaldeon
()
Ответ на: комментарий от kaldeon

I once attended a Java user group meeting where James Gosling (Java’s inventor) was the featured speaker. During the memorable Q&A session, someone asked him: «If you could do Java over again, what would you change?» «I’d leave out classes,» he replied.

А пруфа то и нету, кто-то что-то сказал про Гослинга, а где транскрипция или запись? Возможно его не так поняли или переврали адепты тяп ляп композиции, ведь им нужно было как-то её попиарить?

По приведённому мной линку приводится аудиозапись 18ю годами позже и в ней Гослинг заявляет свою позицию с точностью до наоборот?

sanyo1234
() автор топика
Последнее исправление: sanyo1234 (всего исправлений: 2)
Ответ на: комментарий от kaldeon

Что касается 1% — это цифра, её было бы неплохо подтвердить. У меня есть вот такие данные:

https://pypl.github.io/PYPL.html

https://www.devjobsscanner.com/blog/top-8-most-demanded-programming-languages/

https://spectrum.ieee.org/top-programming-languages-2024#toggle-gdpr

Возможно твоя статистика по популярности Golang и правильная, но даже 7% - это ОЧЕНЬ мало и совсем не показатель.

sanyo1234
() автор топика
Ответ на: комментарий от kaldeon

https://habr.com/ru/articles/325478/

Кроме того, чаще всего, по моим наблюдениям, критики ООП просто не умеют им пользоваться, да и вообще стройно мыслить. Само по себе ООП не поедет, от умения тоже многое зависит.
sanyo1234
() автор топика
Ответ на: комментарий от sanyo1234

Сокращение кода достигается не через наследование, а через использование абстракций.

Абсолютнейшая ЛОЖЬ !!!

Давай приземлим понятия к земле.

Абстракция — это способ ментально отделить и использовать в свою пользу какой-то аспект реальности, который не может существовать отдельно. Именно благодаря абстракциям пользоваться и программировать компьютеры легко. Ты можешь просто делать write, при этом не уточняя, что под капотом происходит передача данных по сети, запись через NVMe или отправка данных в виртуалку.

Наследование — это способ установления отношения вида is-a между несколькими абстракциями. «Машина имеет двигатель» — это has-a, тогда как «собака есть животное» — это is-a. Наследование реализации, в свою очередь, расширяет понятие возможностью переиспользования реализации (разница между private и protected не столь важна).

Сокращение кода, таким образом, достигается засчёт переиспользования реализации в контексте, который ограничен отношением is-a между несколькими абстракциями. Собака есть животное, следовательно я могу обращаться к parent.breathe() как к реализации.

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

Условный Hello World намного проще и компактнее написать без абстракций.

Hello World, скорее всего, будет написан с помощью стандартных потоков. Это уже абстракция, причём очень широкая и весьма успешная.

А по поводу гибкости я уже приводил ранее решение, так что тоже считаю критику гибкости наследования неверной.

Чет я пропустил это решение. Скинь, пожалуйста, ссылку.

Но я приведу пример того, почему я называю наследование негибким. Есть Event и Day — несколько типов объектов, на которые можно подписаться. Допустим, в нашей системе они настолько родственны, что есть основание создать родительский класс Subscribable и включить в него значительную часть общей реализации.

В этот момент происходит привязка к реализации, что нарушает принцип инкапсуляции. Ты не можешь легко заменить Subscribable на, допустим, IntenseSubscribable — то же самое поведение, но с другой механикой.

Кроме того, Event и Day важны в нескольких независимых контекстах. Было бы удобно наследовать сразу несколько реализаций. Тогда мы получаем SubscribableAndShareable (или EventDayable) в роли раздутого класса. Или нам нужно множественное наследование с вытекающими проблемами совместимости (нам нужна будет только часть одной из наследуемых реализаций, другая часть будет противоречить дизайну).

Эти две особенности—нарушение инкапсуляции и необходимость выбора иерархии—я и называю негибкими.

Могу лишь предположить, что ты абсолютно не умеешь использовать наследование в ООП, только и всего.

Понять других людей важнее, чем опровергнуть.

Не велика проблема [прописывать вызовы процедур вручную].

А как ты мерял?

Личный опыт, сравнение с другими нежелательными аспектами создания программ (примеры есть в том же сообщении).

Сокращает ли наследование реализации код? Возможно. Как и процедуры. Позволяет ли оно более просто воспринимать программу? С этим сложнее. Я не уверен.

при использовании композиции и DRY процедур ты вынужден прописывать их вызовы вручну

В программировании есть вещи намного хуже.

Речь о сокращении объёма кода. Что для этого может быть хуже, чем композиция?

Я не хотел сказать, что процедуры могут сравниться или даже опередить наследование в смертельной схватке за истребление объёма кода. Я говорил о том, что это не самое главное. Говорил без деталей, но всё-таки об этом.

Композиция обозначает комбинирование нескольких абстракций в более сложные, при этом не нарушая инкапсуляцию. Опять же, здесь существенная характеристика — абстракции. Выберешь нужные абстракции, будешь их правильно использовать — количество кода сократится.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 7)
Ответ на: комментарий от sanyo1234

Цитата так себе, а вот статья хороша. Чуть позже напишу по ней комментарии.

kaldeon
()
Ответ на: комментарий от kaldeon

Давай приземлим понятия к земле.

Что это значит? Упрощение? Ты IMHO наоборот наворотил усложнения и даже логических несоответствий.

Абстракция — это способ ментально отделить и использовать в свою пользу какой-то аспект реальности,

Почему обязательно в свою пользу? Абстракции бывают и вредными?

который не может существовать отдельно.

Отдельно от чего?

Именно благодаря абстракциям пользоваться и программировать компьютеры легко. Ты можешь просто делать write, при этом не уточняя, что под капотом происходит передача данных по сети, запись через NVMe или отправка данных в виртуалку.

Благодаря правильным полезным абстракциям.

(разница между private и protected не столь важна).

Причём тут это? И почему разница неважна?

Понятия должны быть основаны на существенной (или фундаментальной) характеристике.

Понятия, которые ты «приземляешь» (c)?

Когда группа предметов имеет множество характеристик, которые отличают их от всех остальных предметов, то нужно выявить именно ту, на которой основаны все остальные. В данном контексте (все случаи использования наследования реализации) такой характеристикой является абстрактность, не наследуемость.

Расшифруй своё сообщение. Какое отношение имеет абстрактность к возможности наследования того или иного свойства или метода?

По твоему для выявления общего свойства нужна абстрактность такого свойства, а не его наследуемость? Какой-то бред?

sanyo1234
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)