Здравствуйте, AndrewVK, Вы писали:
G>>На давайте теперь обсудим, кто тут под пивом, а кто под водкой.
AVK>Не я первый начал. И на подобные "аргументы" ничего лучше все равно не изобретешь.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Ikemefula, Вы писали:
IT>>>Не совсем так. Говоря обо всём об этом, я имел ввиду конкретный пример из жизни. Так вот в нём дело было даже не во времени, в количестве геморроя. I>>Ты уже в который раз вместо указания конкретных фактов используешь эмоциональную оценку.
IT>Я уже в который раз пытаюсь кое-кому объяснить, что эмоциональная оценка такие же конкретные факты, как и всё остальное.
Здравствуйте, IT, Вы писали:
IT>>>Не совсем так. Говоря обо всём об этом, я имел ввиду конкретный пример из жизни. Так вот в нём дело было даже не во времени, в количестве геморроя. I>>Ты уже в который раз вместо указания конкретных фактов используешь эмоциональную оценку.
IT>Я уже в который раз пытаюсь кое-кому объяснить, что эмоциональная оценка такие же конкретные факты, как и всё остальное.
Это для тебя она конкретный факт. А для других это эмоциональная оценка. Вполне возможно даже, что та активность которую ты назвал геморроем, кому то будет очень даже нравиться.
Здравствуйте, Gaperton, Вы писали:
I>>>>Автор статьи в этом треде не раз и не два прокололся. А иногда возникает ощущение что он под пивом
AVK>>>У меня ощущение, что под пивом или чем то еще в этом требе как раз ты.
I>>Ты сильно погорячился. А проколы автора вобщем то четко обозначены.
G>Не. ты от ответа не уходи. Ты под пивом или под водкой?
В данном топике все мессаги от меня написаны на трезвую голову.
G>Вот у меня лично сложный состав. В основе — Jack Daniels + Сибирская Корона + Хугарден.
Джек Дениэлс считаю, можно пить только в чистом виде без пива и всякой дряни.
Это не ответ на пост, а вопрос как последнему запостившемуся.
Вопрос, мелкий но конкретный.
Если функция должна вернуть 2-3 параметра как лучше сделать, через out, через Tuple, или дополнительно объявить структуру?
В отрыве от контекста, окружающего кода, может и нет приемуществ ни у одного варианта.
Поэтому вопрос скорее такой, какие факторы полияют выбор ? Т.е. что может повлиять на то что один вариант станет предпочтительнее, какие особенности окружающего кода надо учитывать.
Большой ли список факторов получится?
Вопросы о производительности(выделение динамической памяти на tuple) проигнорируем
3 Варианта:
void Func(out Type1 Name1, out Type2 Name2){...
Здравствуйте, Silver_s, Вы писали:
S_>Вопрос, мелкий но конкретный.
Вопрос вобще говоря не мелкий, про такое написаны целые книги
S_>Если функция должна вернуть 2-3 параметра как лучше сделать, через out, через Tuple, или дополнительно объявить структуру?
out требует понимания указателей, что вобщем то странно ожидать от любого
Туплы идея неплохая, но это жОсткое ограничение если встречается в публичном апи
Структура или класс решает вопрос но количество таких структур снова становится жостким ограничением
есть еще вариант, преобразовать функцию в класс, здесь тоже есть нюансы
S_>Большой ли список факторов получится?
Навскидку, вот
1 как именно будут использоваться возвращаемые значения
2 уровень команды
3 кто будет использовать кроме команды
4 уровень тех кто это будет использовать
5 какие языки будут использоваться
а для внутреннего использования
б для внешнего
6 насколько часто будут использоваться подобные функции
Соответственно, если функция в публичном АПИ, к которому имеют доступ самые разные люди, использовать будут самые разные языки как внутри проекта так и вне, то вариантов не остается — решением будет инстанс конкретного класса или функция преобразованая в класс.
Здравствуйте, Ikemefula, Вы писали:
I>Навскидку, вот I>1 как именно будут использоваться возвращаемые значения I>2 уровень команды I>3 кто будет использовать кроме команды I>4 уровень тех кто это будет использовать I>5 какие языки будут использоваться I> а для внутреннего использования I> б для внешнего I>6 насколько часто будут использоваться подобные функции
А если бы мы задались целью в цифрах это оценить. Состряпать алгоритм чтоб выдавал предпочтительность варианта, или хоть что-то хоть немного похожее на правду. Практической пользы от такого алгоритма может бы и не было, но хотя бы посмотреть насколько все запутано (какую-то сложность, читабельность).
Список уже большой, если пункты начать раскрывать еще вложенные списки полезут.
Там всякие мелочи. Например в Tuple безымянные поля, в остальных вариантах именнованые. v.First может быть хуже чем внятное Name1.
Если забудешь что закреплено за первым элементом, прийдется лезть читать коментарии к функции, что она в Tuple возвращает.
А комментарий еще надо написать, если его нет прийдется читать функцию, что гораздо сложнее.
Но если код так организован что область видимости функции очень маленькая, и читая места ее использования все равно и функцию прийдется прочитать. Тогда недостатки от безымянности уменьшаются.
Если структуру создашь, то как минимум еще одна сущность будет глаза мозолить. Глядя на нее может быть непонятно где она используется, только для возврата из одной функции или где-то еще. Кроме того для нее может оказаться сложно придумать название, т.к. по смыслу два возвращаемых параметра не обязательно сильно сцеплены. Читабельность кода может и снизиться когда везде разбросаны всякие небольшие структурки с невнятными названиями, с невнятной областью видимости. Когда реальная область видимости/действия очень маленькая, а кажущаяся чуть ли не весь проект. Чтобы это узнать еще прийдется тулзы запускать для поиска использований. (Например сменишь поле с double на int, если не выскочит ошибка это еще не значит что ее никто не использует в другом месте, и может где-то что-то отвалится)
Здравствуйте, Silver_s, Вы писали:
S_> Список уже большой, если пункты начать раскрывать еще вложенные списки полезут. S_>Там всякие мелочи. Например в Tuple безымянные поля, в остальных вариантах именнованые. v.First может быть хуже чем внятное Name1. S_>Если забудешь что закреплено за первым элементом, прийдется лезть читать коментарии к функции, что она в Tuple возвращает. S_>А комментарий еще надо написать, если его нет прийдется читать функцию, что гораздо сложнее. S_>Но если код так организован что область видимости функции очень маленькая, и читая места ее использования все равно и функцию прийдется прочитать. Тогда недостатки от безымянности уменьшаются.
Тупл без механизмов распаковки (ПМ или хотя бы питоновский sequence unpacking) — чемодан без ручки.
Здравствуйте, Silver_s, Вы писали:
S_> А если бы мы задались целью в цифрах это оценить. Состряпать алгоритм чтоб выдавал предпочтительность варианта, или хоть что-то хоть немного похожее на правду. Практической пользы от такого алгоритма может бы и не было, но хотя бы посмотреть насколько все запутано (какую-то сложность, читабельность).
Для алгоритма нужно снять более менее толковые данные.
Практическая польза такого алгоритма просто адская — это вобщем то получится алгоритм принятия решения
S_> Список уже большой, если пункты начать раскрывать еще вложенные списки полезут.
Разумеется. Я только основные пункты указал. Раскрывать их можно до бесконечности
Здравствуйте, Gaperton, Вы писали:
G>>>Но это не главное. Главное, что ты, наконец, не уследил за собой, и нечаянно охарактеризовал "сложность" через время и трудозатраты, связанные с внесением правки. IT>>Не совсем так. Говоря обо всём об этом, я имел ввиду конкретный пример из жизни. Так вот в нём дело было даже не во времени, в количестве геморроя. Если интересно могу об этом случае рассказать подробнее. G>Валяй, расскажи. Не вижу причин, почему нет — на конкретику всегда полезно перейти. Будет интересно.
Ага. Ну так вот. Есть у нас одно приложение, которое можно охарактеризовать как data driven application. В общем, пользователи заливают в него свои данные, а оно их как-то там процессит, переливает из пустого в порожнее, объединяет, разъединяет, генерирует, группирует, агрегирует и т.д. Алгоритмы и методологии процессинга весьма разнообразны, так же как и разнообразны средства и способы, с помощью которых они реализованы. Есть среди этих средств в том числе и SQL скрипты, наборы сохранённых процедур, которые занимаются тем, что в зависимости от введённых пользователем данных, динамически создают и выполняют наборы SQL комманд.
Эти скрипты работают как надо и давно отлажены. Единственная проблема — иногда приходится разбираться с тем, что они там, как и зачем понагенерировали. Как правило наши пользователи сами в состоянии разобраться со своими данными, но иногда они попадают в затруднительные ситуации и нам приходится им помогать искать концы. Иногда приходится разбираться с производительностью сгенерированного SQL. Нормальные средства отладки в Sybase отсутствуют, самым доступным средством является команда SELECT xxx, да и с ней проблемы, например, DBArtizan обрезает отображаемые строки до 256 символов, а наш результирующий SQL может легко составлять несколько килобайт. Ещё Sybase теряет контекст вызова, если исользовать команду Execute. Т.е. в случае вылета мы не знаем даже какая из сохранённых процедур дала дуба. В общем, каждый раз фан по полной программе.
Сейчас это всё переписано на C# и проблема как-то сама собой исчезла. Разбираться с данными и запросами всё ещё приходится, но теперь это на порядок быстрее. Фактически время тратится только на анализ самой проблемы, а не на получение данных для анализа, как это было раньше.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Gaperton, Вы писали:
IT>>Я уже в который раз пытаюсь кое-кому объяснить, что эмоциональная оценка такие же конкретные факты, как и всё остальное. G>Почитай, что мы, менеджеры, пишем про эмоциональную оценку. Будет интересно. Примерь на себя. G>http://gaperton.livejournal.com/50685.html
Всё правильно. Я бы только ещё добавил категорию задач, которые являются заведомо геморройными и тогда картина будет полной.
G>Hint: некоторые из нас, менеджеров, не боятся "грязной работы", и иногда устраивают себе испытание: заставляют себя тряхнуть стариной, и в полный рост кодить. Из принципа, чтобы не отрываться от реальности. Редкость, но бывает, ага. И тогда появляются такие статьи.
Молодца! Мой босс тоже периодически тренирует польчики, чтобы не забыть как код писать
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
IT>>>>Не совсем так. Говоря обо всём об этом, я имел ввиду конкретный пример из жизни. Так вот в нём дело было даже не во времени, в количестве геморроя. I>>>Ты уже в который раз вместо указания конкретных фактов используешь эмоциональную оценку.
IT>>Я уже в который раз пытаюсь кое-кому объяснить, что эмоциональная оценка такие же конкретные факты, как и всё остальное.
G>Сложной от эмоций не зависит.
Если рассматривать отношение метрик объем/время как характеристику сложности, то совершенно объективно — сложность зависит от эмоций. И иногда — очень сильно. http://gaperton.livejournal.com/50685.html
А вот если не рассматривать — то можно вообще что угодно говорить. Метафизика.
Здравствуйте, IT, Вы писали:
IT>>>Я уже в который раз пытаюсь кое-кому объяснить, что эмоциональная оценка такие же конкретные факты, как и всё остальное. G>>Почитай, что мы, менеджеры, пишем про эмоциональную оценку. Будет интересно. Примерь на себя. G>>http://gaperton.livejournal.com/50685.html
IT>Всё правильно. Я бы только ещё добавил категорию задач, которые являются заведомо геморройными и тогда картина будет полной.
Здравствуйте, IT, Вы писали:
G>>Hint: некоторые из нас, менеджеров, не боятся "грязной работы", и иногда устраивают себе испытание: заставляют себя тряхнуть стариной, и в полный рост кодить. Из принципа, чтобы не отрываться от реальности. Редкость, но бывает, ага. И тогда появляются такие статьи.
IT>Молодца! Мой босс тоже периодически тренирует польчики, чтобы не забыть как код писать
Ну, тебе тоже надо иногда руководить . Не менее полезно для познания реальности во всех ее гранях.
А реальность такова, что планирование — это та же самая инженерная работа. Нет в менеджерской работе ничего менеджерского, чуждого инженерам. План — это архитектура/дизайн, растянутые во времени.
Огромный плюс советской конструкторской школы в том, что в ней это никогда не ставилось под сомнение.
Здравствуйте, IT, Вы писали:
G>>>>Но это не главное. Главное, что ты, наконец, не уследил за собой, и нечаянно охарактеризовал "сложность" через время и трудозатраты, связанные с внесением правки. IT>>>Не совсем так. Говоря обо всём об этом, я имел ввиду конкретный пример из жизни. Так вот в нём дело было даже не во времени, в количестве геморроя. Если интересно могу об этом случае рассказать подробнее.
Это оставляем, чтобы не забыть, зачем.
G>>Валяй, расскажи. Не вижу причин, почему нет — на конкретику всегда полезно перейти. Будет интересно.
IT>Ага. Ну так вот. Есть у нас одно приложение, которое можно охарактеризовать как data driven application. В общем, пользователи заливают в него свои данные, а оно их как-то там процессит, переливает из пустого в порожнее, объединяет, разъединяет, генерирует, группирует, агрегирует и т.д. Алгоритмы и методологии процессинга весьма разнообразны, так же как и разнообразны средства и способы, с помощью которых они реализованы. Есть среди этих средств в том числе и SQL скрипты, наборы сохранённых процедур, которые занимаются тем, что в зависимости от введённых пользователем данных, динамически создают и выполняют наборы SQL комманд.
Ясно.
IT>Эти скрипты работают как надо и давно отлажены. Единственная проблема — иногда приходится разбираться с тем, что они там, как и зачем понагенерировали. Как правило наши пользователи сами в состоянии разобраться со своими данными, но иногда они попадают в затруднительные ситуации и нам приходится им помогать искать концы. Иногда приходится разбираться с производительностью сгенерированного SQL. Нормальные средства отладки в Sybase отсутствуют, самым доступным средством является команда SELECT xxx, да и с ней проблемы, например, DBArtizan обрезает отображаемые строки до 256 символов, а наш результирующий SQL может легко составлять несколько килобайт. Ещё Sybase теряет контекст вызова, если исользовать команду Execute. Т.е. в случае вылета мы не знаем даже какая из сохранённых процедур дала дуба. В общем, каждый раз фан по полной программе.
Другими словами, мы как правило имеем в этот в целом прекрасно работающий код дорогую правку. Будь то дефект, или фича.
Но ты говоришь про повышенную цену выполнения сервисных запросов класса "Investigation", которые вовсе не обязательно приводят к правке — разве что если в процессе разбирательств ты дефект найдешь.
Это конечно, уже никакая не правка, но вполне укладывается в "затраты на поддержку и сопровождение". Совсем небольшое обобщение. Спасибо, учту. Я чуть более чем это требуется сузил класс затрат времени, привязав его к внесению правок.
Можно пытаться выделять отдельные статьи трат времени (и связанной с этим сложности), например, reverse engineering (результат деятельности — понимание), и перечислять их. А можно несколько обобщить до "трат времени, связанных с кодом".
В целом, если разобрать основные траты времени, специфичные для существующего кода, их будет не так много:
1) Затраты на диагностику проблем/разбор ситуаций — понимание, почему именно оно так работает в конкретном случае. Это, по сути, восстановление "детального дизайна".
2) Затраты на reverse engineering (понимание, как оно в целом устроено и работает. "дизайн"+"детальный дизайн").
3) Затраты на рефакторинг (изменение без добавления/изменения функциональности, но, возможно, с одновременным исправлением дефектов).
И все. Каждая трата может быть измерена. Это не означает, что ее надо секундомером измерять — но означает:
— что ее легко интуитивно оценить.
— это можно сравнивать.
— разные люди одинаково поймут.
Привязка твоего классификатора сложности к объективно измеримым вещам только выиграет от этого.
"Классификатор ошибок" в этом деле играет фундаментальную роль. Почему. Каждому типу ошибки соответствует определенный класс технических решений, которые ты можешь принять. И в любом решении ты можешь ошибиться — это отличительная характеристика решения. То есть, не может быть технического решения без возможности ошибки, и ошибки без стоящего за ней технического решения.
Описываемая тобой "сложность" может быть объективно наблюдаема (иметь вполне конкретные наблюдаемые последствия) через совокупность данных по ошибкам, времени, и объему. Что, в общем, совсем не плохо, разве нет? Это дополнительный факт, который может (если его не игнорировать) нам много чего дать.
IT>Сейчас это всё переписано на C# и проблема как-то сама собой исчезла. Разбираться с данными и запросами всё ещё приходится, но теперь это на порядок быстрее. Фактически время тратится только на анализ самой проблемы, а не на получение данных для анализа, как это было раньше.
То есть, в результате переписывания, ты уменьшил стоимость сопровождения этого кода. Ну, отлично .
Если бы тебе не приходилось на этот работающий код времени тратить, ты бы не стал его трогать, правильно?
Здравствуйте, Ikemefula, Вы писали:
G>>Не. ты от ответа не уходи. Ты под пивом или под водкой?
I>В данном топике все мессаги от меня написаны на трезвую голову.
То есть, ты будучи в трезвом уме и сознании взялся комментить в "философию программирования"?
G>>Вот у меня лично сложный состав. В основе — Jack Daniels + Сибирская Корона + Хугарден.
I>Джек Дениэлс считаю, можно пить только в чистом виде без пива и всякой дряни.
Вот за что я люблю РСДН. Не забалуешь тут. Зайдешь в философию выпимши — так тебе до кучи еще и объяснят, что ты и пьешь-то неправильно .
Здравствуйте, IT, Вы писали:
G>>Ну вот уже напрашиваются метрики: время выполнения и количество багов. Причем не важны абсолютные цифры, важно что ты можешь подходы упорядочить по этим метрикам.
IT>Как можно упорядочить баги, если один является орфографической ошибкой в строке и требует 2 секунды на фикс, а другой является следствием архитектурной ошибки и требует для фикса переписать 2/3 приложения?
Да так и упорядочивают — по виду технического решения, в котором найдена бага.
0) Требования. Ошибочные предстваления о том, что надо сделать.
1) Архитектурная. Неверный выбор базовых технологий и/или общих принципов построения системы.
2) Дизайн. "Структурная" ошибка. Неверная нарезка функциональности на компоненты.
3) Детальный дизайн. Ошибка в алгоритмах или структурах данных.
4) Кодирование. Здесь понятно.
Понятно также, что чем выше уровнем техническое решение, тем дороже ошибка.
Среднее время фикса, посчитанное для каждого класса (включая все связанные с разработкой фикса затраты), будет убывать по мере продвижения по списку. Это и есть "стоимость ошибки".
Наблюдается также еще одна весьма любопытная статистическая закономерность. В целом, время (затраты) на фикс (включая диагностику ошибки, разработку решения, и вообще все связанные затраты) коррелирует со временем, прошедшим с момента внесения ошибки, до ее обнаружения.
То есть, "старые" ошибки обходятся дороже, чем новые. Исходя из этого, процесс разработки будет недурно построить таким образом, чтобы те же самые ошибки находились пораньше. В этом и состоит смысл внедрения код и дизайн ревью.
Точно так же, если большой проблемы с ценой и количеством ошибок у нас по факту нет (что измеримо) — то нет большого смысла вводить и ревью. Или, скажем, если наши ревью не позволяют находить ошибок — то они в таком виде не сильно-то и нужны.