Re[42]: Как не надо писать код
От: AlexNek  
Дата: 25.04.11 21:25
Оценка:
Здравствуйте, samius, Вы писали:

s> s>> Походу вы собираетесь и дальше препираться на тему можно ли трактовать результат TryGetValue кодом возврата, вместо того что бы согласиться что TryGetValue позволяет разобраться как с корректностью аргумента, так и с наличием записи?


s> AN>Про корректность аргументов там ничего не сказано.


s> см. секцию исключений

Мы вроде о Return Value говорили.

s> s>> Битая команда и нераспознаный в корректных данных символ — это весьма далекие ситуации.


s> AN>Из-за этой команды головка хреново синхронизировалась со сканером и символ/строку уже не распознать, их может просто не быть там.


s> Во! Из-за битой команды может пострадать результат сканирования, потому ситуации с битыми командами надо как минимум протоколировать и разбираться с ними, что бы максимально исключить возможность порчи данных команды.

С этим можно разбираться на этапе отладки, пользователь пересылать логи не будет.
s> Однако ситуация с нераспознаванием символа/строки может случиться и с валидной командой для головки, например из-за дефекта носителя. Это вообще норма, с этим ничего сделать нельзя, в этом софт не виноват и крайних искать не надо, так же как и исправлять что-либо. Т.е. одно может быть следствием другого, но не признаком другого.
В данном случае, пользователь просто получит чистый лист с надписью — нет обмена со сканером. И произойти это может по многим причинам, например вместо сканера подключили принтер.
Смысл в том что я рассматриваю функцию в конексте, вы же хотите ее рассматривать обобщенно. Для обобшенной функции нужно было делать именно так как вы говорите.
Для конкретного контекста по барабану, либо функция будет кричать, затем мы будет крик игнорировать наверху, и затем выдавать "нулевые данные", либо функция будет сразу выдавать "нулевые данные"

s> s>> s>> Как считаете, для чего дан перечень исключений методов WriteLine, разве для того что бы их не ловили?


s> AN>вопрос в том что это даст практически?


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

Вот как раз и подошли к отличию "общих" функций от "конкретных".
Для "конкретных" не нужна никакая возможность выбора пути 1 или пути 2. Путь уже задан контекстом.
s> Обычно это не требуется, но если взять тот же пример, когда работа не должна убиваться при ошибке вывода в консоль (IO или FormatException), программист может обработать эту ситуацию.
И как ее обработать глобально? Делать враппер?
s> В другом случае он не будет спеицальным образом обрабатывать эти исключения и получит FailFast, который позволит увидеть проблему на раннем этапе.
Да плевать мне на консоль, единственная ее полезность вывод информации, а если этой возможности нет, то она мне нафиг не нужна.

s> AN>Вообще то в консольной программе мессаже бох не должен вообще появляться.


s> Это была не моя идея. Но там вместо MessageBox может стоять запись в лог файл.

Запись в лог файл и так будет в обработчике ошибок, но мне нужно при этом игнорировать все ошибки вывода на консоль для продолжения работы программы, т.е. нужно специально писать обвертку для заглушки исключений.
s> AN>А противоречие тут в том, что проге при данной ошибке приходит каюк, она становится немой, но если работа проги не заключается в выводе данных на консоль, то ей на это исключение нужно просто плевать, а она не может потому как нормальный путь нарушен.

s> Я тут не вижу противоречия. Если программа должна плевать — она может позволить себе плевать и следовать нормальному пути.

И какой ценой это достигается?
s> Если не должна плевать — может позволить обрабатывать исключение на этом же уровне или выше.
"Если" в данном случае просто не существует, есть только один единственный путь, по которому разрешено идти.

s> s>> AN>И что даст это исключение для пользователя, в данном случае?


s> s>> Открою секрет, что ловля исключений подразумевает не только показ MessageBox-а пользователю. В частности, например, гашение исключения позволит коду работать дальше, невзирая на случившиеся проблемы.

Но для гашения исключения нужно оборачивать каждый вызов. Или?

s> AN>То бишь вначале генерим то что нам не нужно, а после пытаемся это игнорировать.


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

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

s> s>> Проброс его наверх предоставит выбор вызывающему коду, обертывание позволит классифицировать исключение специальным образом.

Это все верно для "библиотечной" функции.

s> AN>Ну это если возможны варианты. А если есть всегда в данной части кода только вариант

s> AN>с "гашением"?

s> Хотя бы сбросить в лог для дальнейшего разбора полетов.

Лог может выводить и сама функция если это требуется. Зачем наполнять ведро зелеными помидорами и затем их выбрасывать, чтобы передать дальше пустое ведро?

s> s>> В любом случае, если код данного уровня не предполагает о том, как должно быть обработано исключение, он и не должен его перехватывать и уж тем более показывать пользователю MessageBox.

В том и дело что код данноего уровня должне игнорировать исключение и послать "нулевые данные"

s> AN>Так что же нужно делать по этому исключению?

s> AN>вот именно это и хотелось бы узнать.

s> Выяснять и устранять причины битых данных. Если причин нет, то исключение не помеха, а страж.

И как же выяснить и усранить причину не вывода в консоль?

s> s>> Механизм исключений для того и предназначен, что бы извещать пользователя, разработчика, или еще кого. Но делает это он именно на том уровне, где стоят обработчики. Тыкать обработчики на каждый вызов — не очень умно.


s> AN>А есть вариант "глобального гашения"?


s> Любое глобальное решение не подразумевает продолжение работы с места возбуждения без оборачивания кода в try/catch.

Вот именно это я хотел сказать, нафига заниматься пустым обворачиванием?

s> AN>Понимаете, я не явлюсь противником использования исключений, а только хочу сказать, что их использование не подразумевает 100% покрытие. Нам нужна какая либо реакция на ошибку и не всегда нужно кричать об ошибке.


s> Для начала надо научиться отличать ошибки в логике программы, от ошибок окружения, данных и т.п. О первых надо кричать, если только вы не хотите создать у пользователя впечатления о том что программа работает, когда она уже пошла в разнос.

Нужно ещ определится является ли нулевой буфер следствием ошибки в логике программы или это просто возможные данные?

s> AN>Ну типа выезжаю я на перекресток по главной улице и вижу машину которая также думает, что едет по главной. Да можно и посигналить и дождаться стражей порядка после аварии, но можно и просто притормозить. Конечно, в этом случае никто не узнает о нарушении. Но вопрос в том, что будет лучше в определенных ситуациях: кричать о нарушении или промолчать?


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

Где Вы увидели рассогласование данных? Есть неверные данные на входе. Вы считает что их не следует передавать дальше, а согласно задания нужно в этом случае передавать "нулевые данные".
s> Если после вы захотите разобраться, отчего такой глюк произошел, у вас должна быть хоть какая-то информация. Я не настаиваю что это должна быть ажурная надпись на airbag-е, выскочившая в процессе экстренного маневрирования (аналог MessageBox-а). Но хоть что-то, с чем сервисмен разберется, подключив диагностическую колодку.
Вот этого как раз и не требуется, в данном конкретном случае.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[43]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.04.11 08:12
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> см. секцию исключений

AN>Мы вроде о Return Value говорили.
Я говорил о том что вызывающему можно узнать как о нарушении/соблюдении контракта, так и об удаче завершения, и делать между ними различия.

s>> Во! Из-за битой команды может пострадать результат сканирования, потому ситуации с битыми командами надо как минимум протоколировать и разбираться с ними, что бы максимально исключить возможность порчи данных команды.

AN>С этим можно разбираться на этапе отладки, пользователь пересылать логи не будет.
И что, на этапе отладки у вас один код, в продакшне другой?

AN>В данном случае, пользователь просто получит чистый лист с надписью — нет обмена со сканером. И произойти это может по многим причинам, например вместо сканера подключили принтер.

Я говорю об ошибках формирования команды для сканера и то что они будут провоцировать 100% неадекватное поведение сканера. Но мне уже надоело об этом говорить.

AN>Смысл в том что я рассматриваю функцию в конексте, вы же хотите ее рассматривать обобщенно. Для обобшенной функции нужно было делать именно так как вы говорите.

Относительно чего тут обобщение возникает?
AN>Для конкретного контекста по барабану, либо функция будет кричать, затем мы будет крик игнорировать наверху, и затем выдавать "нулевые данные", либо функция будет сразу выдавать "нулевые данные"
Дак напишите что бы она всегда выдавала "нулевые данные", раз по барабану. Меньше кода будет.

s>> Обычно это не требуется, но если взять тот же пример, когда работа не должна убиваться при ошибке вывода в консоль (IO или FormatException), программист может обработать эту ситуацию.

AN>И как ее обработать глобально? Делать враппер?
Выделять абстракцию
s>> В другом случае он не будет спеицальным образом обрабатывать эти исключения и получит FailFast, который позволит увидеть проблему на раннем этапе.
AN>Да плевать мне на консоль, единственная ее полезность вывод информации, а если этой возможности нет, то она мне нафиг не нужна.
Прекрасно Результат будете netsend-ом пользователю высылать?

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

Из обработчика уже не впрыгнуть обратно, если только им не каждый чих обернут, что бы иметь возможность перейти к следующему чиху. Потому выделение абстракции тут довольно разумный компромисс, который позволит не тыкать обработчики на каждый вызов.
s>> Я тут не вижу противоречия. Если программа должна плевать — она может позволить себе плевать и следовать нормальному пути.
AN>И какой ценой это достигается?
небольшой. Выделение абстракции + указание нужной политики. Код даже не будет изменяться при смене политики.
s>> Если не должна плевать — может позволить обрабатывать исключение на этом же уровне или выше.
AN>"Если" в данном случае просто не существует, есть только один единственный путь, по которому разрешено идти.
А как же путь "этапа отладки"? Выше вы явно обозначили что на этапе отладки что-то там решается, значит там другой код? Иначе если тот же, то отладку он только запутает.

AN>Но для гашения исключения нужно оборачивать каждый вызов. Или?

выделять абстракцию

AN>Ну из того, что Вы не видите смысла, из за этого не следует, что ее не нужно посылать. Долго объяснять зачем, но так требует протокол устройства.

Если он так же требует скрывать факт формирования неверной команды, то я умываю руки.

s>> s>> Проброс его наверх предоставит выбор вызывающему коду, обертывание позволит классифицировать исключение специальным образом.

AN>Это все верно для "библиотечной" функции.
Компилятор не делает разницы между "библиотечными" функциями и не "библиотечными". Потому вышеописанное верно для всех функций.

s>> Хотя бы сбросить в лог для дальнейшего разбора полетов.

AN>Лог может выводить и сама функция если это требуется. Зачем наполнять ведро зелеными помидорами и затем их выбрасывать, чтобы передать дальше пустое ведро?
Блин, нет слов, одни эмоции! У вас функция что ли будет решать, заполнять ли ведро помидорами? Сделайте так что бы решала конфигурация а не функция, тогда управлять, что делать с ведром (совать в лог, кидать исключение, либо жевать на месте) можно будет не перекомпилируя. Но это не должно оставаться в том виде, что сейчас. Я бы так не сделал, но вам виднее.

AN>В том и дело что код данноего уровня должне игнорировать исключение и послать "нулевые данные"



s>> Выяснять и устранять причины битых данных. Если причин нет, то исключение не помеха, а страж.

AN>И как же выяснить и усранить причину не вывода в консоль?
Для начала обеспечить разработчика информацией о том что вывод в консоль окончился неудачей. Если этого нет, то никто и не узнает, что там в консоль чего-то не попало. А потом уж разработчик должен включать голову, как выяснить причину и устранить.

s>> Любое глобальное решение не подразумевает продолжение работы с места возбуждения без оборачивания кода в try/catch.

AN>Вот именно это я хотел сказать, нафига заниматься пустым обворачиванием?
Пустым как раз и нафига. Надо заниматься оборачиванием с пониманием ради чего. Например, выделение абстракции над консолью позволит оборачивать не все вызовы консоли, а только те что в реализации абстракции. А их O(1) штук относительно объема кода всей программы.

AN>Нужно ещ определится является ли нулевой буфер следствием ошибки в логике программы или это просто возможные данные?

Нулевой — это вопрос. А является ли ошибкой переполненный bufferLength?

AN>Где Вы увидели рассогласование данных? Есть неверные данные на входе. Вы считает что их не следует передавать дальше, а согласно задания нужно в этом случае передавать "нулевые данные".

Передавайте, если вам не интересна причина возникновения неверных данных.

s>> Если после вы захотите разобраться, отчего такой глюк произошел, у вас должна быть хоть какая-то информация. Я не настаиваю что это должна быть ажурная надпись на airbag-е, выскочившая в процессе экстренного маневрирования (аналог MessageBox-а). Но хоть что-то, с чем сервисмен разберется, подключив диагностическую колодку.

AN>Вот этого как раз и не требуется, в данном конкретном случае.
На том и остановимся.
Re[44]: Как не надо писать код
От: AlexNek  
Дата: 26.04.11 13:07
Оценка:
Здравствуйте, samius, Вы писали:

s> s>> см. секцию исключений


s> AN>Мы вроде о Return Value говорили.


s> Я говорил о том что вызывающему можно узнать как о нарушении/соблюдении контракта, так и об удаче завершения, и делать между ними различия.

Но это нельзя сделать исключительно из значения поля возврата.

s> s>> Во! Из-за битой команды может пострадать результат сканирования, потому ситуации с битыми командами надо как минимум протоколировать и разбираться с ними, что бы максимально исключить возможность порчи данных команды.


s> AN>С этим можно разбираться на этапе отладки, пользователь пересылать логи не будет.


s> И что, на этапе отладки у вас один код, в продакшне другой?

В продакшин нет столь подробных логов.

s> AN>В данном случае, пользователь просто получит чистый лист с надписью — нет обмена со сканером. И произойти это может по многим причинам, например вместо сканера подключили принтер.


s> Я говорю об ошибках формирования команды для сканера и то что они будут провоцировать 100% неадекватное поведение сканера. Но мне уже надоело об этом говорить.

Так именно этого и нет, вы отчего то это себе представили.

s> AN>Смысл в том что я рассматриваю функцию в контексте, вы же хотите ее рассматривать обобщенно. Для обобшенной функции нужно было делать именно так как вы говорите.


s> Относительно чего тут обобщение возникает?

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

s> AN>Для конкретного контекста по барабану, либо функция будет кричать, затем мы будет крик игнорировать наверху, и затем выдавать "нулевые данные", либо функция будет сразу выдавать "нулевые данные"


s> Дак напишите что бы она всегда выдавала "нулевые данные", раз по барабану. Меньше кода будет.

"Нулевые данные" нужны в случае каких либо ошибочных ситуаций.

s> s>> Обычно это не требуется, но если взять тот же пример, когда работа не должна убиваться при ошибке вывода в консоль (IO или FormatException), программист может обработать эту ситуацию.


s> AN>И как ее обработать глобально? Делать враппер?


s> Выделять абстракцию

А более определенно?

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


s> AN>Да плевать мне на консоль, единственная ее полезность вывод информации, а если этой возможности нет, то она мне нафиг не нужна.


s> Прекрасно Результат будете netsend-ом пользователю высылать?

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

s> AN>Запись в лог файл и так будет в обработчике ошибок, но мне нужно при этом игнорировать все ошибки вывода на консоль для продолжения работы программы, т.е. нужно специально писать обвертку для заглушки исключений.


s> s>> Я тут не вижу противоречия. Если программа должна плевать — она может позволить себе плевать и следовать нормальному пути.


s> AN>И какой ценой это достигается?


s> небольшой. Выделение абстракции + указание нужной политики. Код даже не будет изменяться при смене политики.

Примерчик можно?

s> s>> Если не должна плевать — может позволить обрабатывать исключение на этом же уровне или выше.


s> AN>"Если" в данном случае просто не существует, есть только один единственный путь, по которому разрешено идти.


s> А как же путь "этапа отладки"? Выше вы явно обозначили что на этапе отладки что-то там решается, значит там другой код? Иначе если тот же, то отладку он только запутает.

На этапе отладки только больше информации, и то "по заказу"

s> AN>Но для гашения исключения нужно оборачивать каждый вызов. Или?


s> выделять абстракцию

сорри, слишком абстрактно .....

s> AN>Ну из того, что Вы не видите смысла, из за этого не следует, что ее не нужно посылать. Долго объяснять зачем, но так требует протокол устройства.


s> Если он так же требует скрывать факт формирования неверной команды, то я умываю руки.

Требуется при любой ошибочной ситуации передачи посылать "пустую команду".

s> s>> s>> Проброс его наверх предоставит выбор вызывающему коду, обертывание позволит классифицировать исключение специальным образом.


s> AN>Это все верно для "библиотечной" функции.


s> Компилятор не делает разницы между "библиотечными" функциями и не "библиотечными". Потому вышеописанное верно для всех функций.

А при чем здесь компилятор?
Вот скажем два "абстрактных" варианта, используются в одном единственном месте.
Насколько они эквивалентны?
if (f(ref x) == error)
{
 x = 0
}
...
f(ref x)
{
 if (input_error)
 {
   return error;
 }  
}


f(ref x);
...
f(ref x)
{
 if (input_error)
 {
   x = 0;
 }
}


s> s>> Хотя бы сбросить в лог для дальнейшего разбора полетов.


s> AN>Лог может выводить и сама функция если это требуется. Зачем наполнять ведро зелеными помидорами и затем их выбрасывать, чтобы передать дальше пустое ведро?


s> Блин, нет слов, одни эмоции! У вас функция что ли будет решать, заполнять ли ведро помидорами? Сделайте так что бы решала конфигурация а не функция, тогда управлять, что делать с ведром (совать в лог, кидать исключение, либо жевать на месте) можно будет не перекомпилируя. Но это не должно оставаться в том виде, что сейчас. Я бы так не сделал, но вам виднее.


s> AN>В том и дело что код данного уровня должен игнорировать исключение и послать "нулевые данные"


s>

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

s> s>> Выяснять и устранять причины битых данных. Если причин нет, то исключение не помеха, а страж.


s> AN>И как же выяснить и устранить причину не вывода в консоль?


s> Для начала обеспечить разработчика информацией о том что вывод в консоль окончился неудачей.

Для чего? Программа отработала как требовалось.
s> Если этого нет, то никто и не узнает, что там в консоль чего-то не попало. А потом уж разработчик должен включать голову, как выяснить причину и устранить.
Как и говорил, в общем случае это все верно, но когда, допустим я запускаю программу из другой программы, то вывод на консоль меня совсем не интересует.

s> AN>Нужно ещ определится является ли нулевой буфер следствием ошибки в логике программы или это просто возможные данные?


s> Нулевой — это вопрос. А является ли ошибкой переполненный bufferLength?

По идее это также ошибка.

s> AN>Где Вы увидели рассогласование данных? Есть неверные данные на входе. Вы считает что их не следует передавать дальше, а согласно задания нужно в этом случае передавать "нулевые данные".


s> Передавайте, если вам не интересна причина возникновения неверных данных.

Именно в данном случае неинтересна. Было задание передать ошибочные данные, передать их нельзя, поэтому передалась только информация что были какие то данные.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[45]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.04.11 14:22
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> Я говорил о том что вызывающему можно узнать как о нарушении/соблюдении контракта, так и об удаче завершения, и делать между ними различия.

AN>Но это нельзя сделать исключительно из значения поля возврата.
Никто не утвреждал что это делается исключительно возвращаемым значением.

s>> И что, на этапе отладки у вас один код, в продакшне другой?

AN>В продакшин нет столь подробных логов.
их что, кто-то убирает при выпуске версии?

s>> Я говорю об ошибках формирования команды для сканера и то что они будут провоцировать 100% неадекватное поведение сканера. Но мне уже надоело об этом говорить.

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

s>> Относительно чего тут обобщение возникает?

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

AN>"Нулевые данные" нужны в случае каких либо ошибочных ситуаций.

Исходный вариант функции не несет в себе анализа на некоторые ошибочные ситуации.

s>> AN>И как ее обработать глобально? Делать враппер?


s>> Выделять абстракцию

AN>А более определенно?
interface ILog { void WriteLine(string str); ... }


s>> AN>И какой ценой это достигается?


s>> небольшой. Выделение абстракции + указание нужной политики. Код даже не будет изменяться при смене политики.

AN>Примерчик можно?
выше

s>> Если он так же требует скрывать факт формирования неверной команды, то я умываю руки.

AN>Требуется при любой ошибочной ситуации передачи посылать "пустую команду".
Исходный вариант не выполняет это требование. Во-первых в коде нет самой посылки данных, во-вторых возможна ситуация когда буферы не будут созданы.

s>> Компилятор не делает разницы между "библиотечными" функциями и не "библиотечными". Потому вышеописанное верно для всех функций.

AN>А при чем здесь компилятор?
А при чем здесь "библиотечная" функция? Чем работа "библиотечных" функций отличается от остальных?

AN>Вот скажем два "абстрактных" варианта, используются в одном единственном месте.

AN>Насколько они эквивалентны?
AN>
if (f(ref x) == error)
AN>{
AN> x = 0
AN>}
AN>...
AN>f(ref x)
AN>{
AN> if (input_error)
AN> {
AN>   return error;
AN> }  
AN>}
AN>


AN>
f(ref x);
AN>...
AN>f(ref x)
AN>{
AN> if (input_error)
AN> {
AN>   x = 0;
AN> }
AN>}
AN>

Они достаточно эквивалентны в том плане, что я не понимаю, что они делают, что демонстрируют, и нафига там ref-ы.

s>>

AN>Можно конечно, по приходу исключения послать нулевые данные, но что от этого изменится.


s>> Для начала обеспечить разработчика информацией о том что вывод в консоль окончился неудачей.

AN>Для чего? Программа отработала как требовалось.
Есть простая истина. Не все что отработало как требовалось будет и дальше работать как требуется. Особенно после изменения требований или в других сценариях использования.

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

Это не означает что он будет благополучен.

s>> Нулевой — это вопрос. А является ли ошибкой переполненный bufferLength?

AN>По идее это также ошибка.

s>> AN>Где Вы увидели рассогласование данных? Есть неверные данные на входе. Вы считает что их не следует передавать дальше, а согласно задания нужно в этом случае передавать "нулевые данные".


s>> Передавайте, если вам не интересна причина возникновения неверных данных.

AN>Именно в данном случае неинтересна. Было задание передать ошибочные данные, передать их нельзя, поэтому передалась только информация что были какие то данные.
Мне начинает казаться, что вы и есть тот разработчик, которому доверили одну функцию, и кроме выполнения "задания" вас больше ничего не трогает.
Re[46]: Как не надо писать код
От: AlexNek  
Дата: 26.04.11 15:50
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> И что, на этапе отладки у вас один код, в продакшне другой?


s> AN>В продакшин нет столь подробных логов.


s> их что, кто-то убирает при выпуске версии?

Да, дядя препроцессор.

s> s>> Я говорю об ошибках формирования команды для сканера и то что они будут провоцировать 100% неадекватное поведение сканера. Но мне уже надоело об этом говорить.


s> AN>Так именно этого и нет, вы отчего то это себе представили.


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

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

s> s>> Относительно чего тут обобщение возникает?


s> AN>Относительно точки зрения. Если рассматривать какую либо абстрактную функцию, где либо применяемую.


s> К абстрактным функциям, решающим абстрактные задачи где-либо, у меня нет претензий

То есть любой другой функции прерывания не нужны?

s> AN>"Нулевые данные" нужны в случае каких либо ошибочных ситуаций.


s> Исходный вариант функции не несет в себе анализа на некоторые ошибочные ситуации.

Вполне возможно. А что при добавлении исключения это анализ бы появился?

s> s>> AN>И как ее обработать глобально? Делать враппер?


s> s>> Выделять абстракцию


s> AN>А более определенно?


s>
s> interface ILog { void WriteLine(string str); ... }
s>


Ну так это и есть где то что я называю враппером
все равно ILog.WriteLine нельзя написать.

s> s>> AN>И какой ценой это достигается?


s> s>> небольшой. Выделение абстракции + указание нужной политики. Код даже не будет изменяться при смене политики.


s> AN>Примерчик можно?


s> выше

А что тогда политика?

s> s>> Если он так же требует скрывать факт формирования неверной команды, то я умываю руки.


s> AN>Требуется при любой ошибочной ситуации передачи посылать "пустую команду".


s> Исходный вариант не выполняет это требование. Во-первых в коде нет самой посылки данных, во-вторых возможна ситуация когда буферы не будут созданы.

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

s> s>> Компилятор не делает разницы между "библиотечными" функциями и не "библиотечными". Потому вышеописанное верно для всех функций.


s> AN>А при чем здесь компилятор?


s> А при чем здесь "библиотечная" функция? Чем работа "библиотечных" функций отличается от остальных?


s> AN>Вот скажем два "абстрактных" варианта, используются в одном единственном месте.

s> AN>Насколько они эквивалентны?
s> AN>
if (f(ref x) == error)
s> AN>{
s> AN> x = 0
s> AN>}
s> AN>...
s> AN>f(ref x)
s> AN>{
s> AN> if (input_error)
s> AN> {
s> AN>   return error;
s> AN> }
s> AN>}
s> AN>


s> AN>
f(ref x);
s> AN>...
s> AN>f(ref x)
s> AN>{
s> AN> if (input_error)
s> AN> {
s> AN>   x = 0;
s> AN> }
s> AN>}
s> AN>


s> Они достаточно эквивалентны в том плане, что я не понимаю, что они делают, что демонстрируют, и нафига там ref-ы.

ref-ы — чтобы здесь меньше строк писать, да и указывают они на параметр который функция может модифицировать.

Попробую тогда словами описать, это было что то типа псевдокода
Вариант 1
Вызов функции с модифицируемым параметром Х
Если функция возвращает каким либо образом ошибку то параметр Х должен быть равен 0
Реализация функции с параметром Х
Если обнаружены неправильные входные параметры, то сообщаем об ошибке.

Вариант 2
Вызов функции с модифицируемым параметром Х
Реализация функции с параметром Х
Если обнаружены неправильные входные параметры, то устанавливаем параметр Х в 0


s> AN>Можно конечно, по приходу исключения послать нулевые данные, но что от этого изменится.


s> s>> Для начала обеспечить разработчика информацией о том что вывод в консоль окончился неудачей.


s> AN>Для чего? Программа отработала как требовалось.


s> Есть простая истина. Не все что отработало как требовалось будет и дальше работать как требуется. Особенно после изменения требований или в других сценариях использования.

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

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


s> Это не означает что он будет благополучен.

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

s> Мне начинает казаться, что вы и есть тот разработчик, которому доверили одну функцию, и кроме выполнения "задания" вас больше ничего не трогает.

Это ваше право так считать. Но в целом так и должно происходить. Пока задание не изменили/ приостановили его нужно выполнять. Иначе, если каждый будет делать так как считает более правильным командная работа будет весьма затруднена.
Однако никто не запрещает поднять вопрос, а отчего такую фигню нужно делать?
Исторически данная функция изначально имела исключительно лишь входные данные, одним из которых был параметр для вывода дополнительного символа. Все остальные параметры ей были не нужны и были сделаны "на вырост". Если параметр для вывода был в норме то выводился всего лишь дополнительный символ.
Человеку разрешили менять только данную функцию, не меняя поведение остального кода.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[47]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.04.11 16:41
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> их что, кто-то убирает при выпуске версии?

AN>Да, дядя препроцессор.
Жесть

s>> К абстрактным функциям, решающим абстрактные задачи где-либо, у меня нет претензий

AN>То есть любой другой функции прерывания не нужны?
Interrupt?

s>> AN>А более определенно?


s>>
s>> interface ILog { void WriteLine(string str); ... }
s>>


AN>Ну так это и есть где то что я называю враппером

Зря, это не враппер. Это абстракция. Враппером будет реализация этой абстракции.
AN>все равно ILog.WriteLine нельзя написать.
И не требуется. Для того абстракция и вводится, что бы не писать ILog.WriteLine, что по сути эквивалентно Console.WriteLine.

s>> выше

AN>А что тогда политика?
А это конкретная реализация, см. "стратегия".

s>> Исходный вариант не выполняет это требование. Во-первых в коде нет самой посылки данных, во-вторых возможна ситуация когда буферы не будут созданы.

AN>А именно этот код и не должнен посылать данные это всего лишь "врезка" в трубу.
Название не соответствует
AN>Буфер должен тогда быть равен нулю, а это эквивалентно "нулевым данным".
А сразу проверку с возвратом нельзя было сделать? Очень неочевидна логика метода.
AN>Можно конечно сделать и пару различных прерываний, чтобы вызывающий код имел больше информации о происходящем, но зачем?
Полегче с терминами. Если вы об исключениях, то прерывания — это из другой песни.

s>> Они достаточно эквивалентны в том плане, что я не понимаю, что они делают, что демонстрируют, и нафига там ref-ы.

AN>ref-ы — чтобы здесь меньше строк писать, да и указывают они на параметр который функция может модифицировать.

AN>Попробую тогда словами описать, это было что то типа псевдокода

AN>Вариант 1
AN>Вызов функции с модифицируемым параметром Х
AN>Если функция возвращает каким либо образом ошибку то параметр Х должен быть равен 0
AN>Реализация функции с параметром Х
AN>Если обнаружены неправильные входные параметры, то сообщаем об ошибке.
Сообщаем как? Допустимо ли значение параметра 0 при отсутствии ошибки?

AN>Вариант 2

AN>Вызов функции с модифицируемым параметром Х
AN>Реализация функции с параметром Х
AN>Если обнаружены неправильные входные параметры, то устанавливаем параметр Х в 0
Как узнать, что именно было обнаружено неправильного во входных данных?

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

Разве нельзя переопределить вывод в файл на диске только для чтения? Или пользователь ССЗБ?

s>> Это не означает что он будет благополучен.

AN>Конечно, но при нормальной работе вывод на консоль и так никто не видит. при запуске в ручном режиме, вывод на консоль является просто дополнительным бонусом. Если он невозможен, мы его просто игнорируем.
Для того что бы его проигнорировать, надо ввести либо абстракцию, либо try/catch-ить все вызовы WriteLine. Ни того ни другого желания я у вас не обнаружил. Так что походу игнорирование — это просто забивание на исключения.

s>> Мне начинает казаться, что вы и есть тот разработчик, которому доверили одну функцию, и кроме выполнения "задания" вас больше ничего не трогает.

AN>Это ваше право так считать. Но в целом так и должно происходить. Пока задание не изменили/ приостановили его нужно выполнять. Иначе, если каждый будет делать так как считает более правильным командная работа будет весьма затруднена.
Командная работа очень затруднена когда на команду одна думалка, компетентная разбираться в вопросах такого уровня. Хуже только когда их больше одной и у них разные мнения на этот счет.
AN>Однако никто не запрещает поднять вопрос, а отчего такую фигню нужно делать?
Подозреваю, что для этого надо оторвать думалку от решения более важных вопросов...
AN>Исторически данная функция изначально имела исключительно лишь входные данные, одним из которых был параметр для вывода дополнительного символа. Все остальные параметры ей были не нужны и были сделаны "на вырост". Если параметр для вывода был в норме то выводился всего лишь дополнительный символ.
AN>Человеку разрешили менять только данную функцию, не меняя поведение остального кода.
Интересно, сколько платят этому человеку?
Re[48]: Как не надо писать код
От: AlexNek  
Дата: 26.04.11 17:58
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> их что, кто-то убирает при выпуске версии?


s> AN>Да, дядя препроцессор.


s> Жесть

Всегда интересовал перевод этого слова, хотя бы на русский.

s> s>> К абстрактным функциям, решающим абстрактные задачи где-либо, у меня нет претензий


s> AN>То есть любой другой функции прерывания не нужны?


s> Interrupt? Фиг знает почему перещелкнуло, конечно Exception


s> s>> AN>А более определенно?


s> s>>
s> s>> interface ILog { void WriteLine(string str); ... }
s> s>>


s> AN>Ну так это и есть где то что я называю враппером


s> Зря, это не враппер. Это абстракция. Враппером будет реализация этой абстракции.

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

s> AN>все равно ILog.WriteLine нельзя написать.


s> И не требуется. Для того абстракция и вводится, что бы не писать ILog.WriteLine, что по сути эквивалентно Console.WriteLine.

В итоге все равно нужен синглетон или статик.

s> s>> выше


s> AN>А что тогда политика?


s> А это конкретная реализация, см. "стратегия".


s> s>> Исходный вариант не выполняет это требование. Во-первых в коде нет самой посылки данных, во-вторых возможна ситуация когда буферы не будут созданы.


s> AN>А именно этот код и не должнен посылать данные это всего лишь "врезка" в трубу.


s> Название не соответствует

Оно осталось каким и было, да и если не придираться можно сказать что это "трансформация нужная для вывода"

s> AN>Буфер должен тогда быть равен нулю, а это эквивалентно "нулевым данным".


s> А сразу проверку с возвратом нельзя было сделать? Очень неочевидна логика метода.

Так из за логики метод и попал на "доску почета"

s> AN>Можно конечно сделать и пару различных прерываний, чтобы вызывающий код имел больше информации о происходящем, но зачем?


s> Полегче с терминами. Если вы об исключениях, то прерывания — это из другой песни.

Сорри, не знаю отчего переключился,

s> s>> Они достаточно эквивалентны в том плане, что я не понимаю, что они делают, что демонстрируют, и нафига там ref-ы.


s> AN>ref-ы — чтобы здесь меньше строк писать, да и указывают они на параметр который функция может модифицировать.


s> AN>Попробую тогда словами описать, это было что то типа псевдокода

s> AN>Вариант 1
s> AN>Вызов функции с модифицируемым параметром Х
s> AN>Если функция возвращает каким либо образом ошибку то параметр Х должен быть равен 0
s> AN>Реализация функции с параметром Х
s> AN>Если обнаружены неправильные входные параметры, то сообщаем об ошибке.

s> Сообщаем как?

Как именно, абсолютно неважно, "каким либо образом". Эта тоже абстракция только не интерфейсная

s> Допустимо ли значение параметра 0 при отсутствии ошибки?

Да, это ведь просто "врезка в трубу". Функция может здесь быть, а может и нет.

s> AN>Вариант 2

s> AN>Вызов функции с модифицируемым параметром Х
s> AN>Реализация функции с параметром Х
s> AN>Если обнаружены неправильные входные параметры, то устанавливаем параметр Х в 0

s> Как узнать, что именно было обнаружено неправильного во входных данных?

Для чего?

s> AN>Не буду спорить для общего случая, но для примера консольной программы требования могут меняться только на расчеты и других сценариев использования не планируется.


s> Разве нельзя переопределить вывод в файл на диске только для чтения? Или пользователь ССЗБ?

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

s> s>> Это не означает что он будет благополучен.


s> AN>Конечно, но при нормальной работе вывод на консоль и так никто не видит. при запуске в ручном режиме, вывод на консоль является просто дополнительным бонусом. Если он невозможен, мы его просто игнорируем.


s> Для того что бы его проигнорировать, надо ввести либо абстракцию, либо try/catch-ить все вызовы WriteLine. Ни того ни другого желания я у вас не обнаружил. Так что походу игнорирование — это просто забивание на исключения.

А вы много видели программ с абстракцией или try/catch на console?

s> s>> Мне начинает казаться, что вы и есть тот разработчик, которому доверили одну функцию, и кроме выполнения "задания" вас больше ничего не трогает.


s> AN>Это ваше право так считать. Но в целом так и должно происходить. Пока задание не изменили/ приостановили его нужно выполнять. Иначе, если каждый будет делать так как считает более правильным командная работа будет весьма затруднена.


s> Командная работа очень затруднена когда на команду одна думалка, компетентная разбираться в вопросах такого уровня. Хуже только когда их больше одной и у них разные мнения на этот счет.

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

s> AN>Исторически данная функция изначально имела исключительно лишь входные данные, одним из которых был параметр для вывода дополнительного символа. Все остальные параметры ей были не нужны и были сделаны "на вырост". Если параметр для вывода был в норме то выводился всего лишь дополнительный символ.

s> AN>Человеку разрешили менять только данную функцию, не меняя поведение остального кода.

s> Интересно, сколько платят этому человеку?

Сколько кому платят знает только бухгалтерия.
Просто каждого человека нужно использовать там где он больше всего приносит пользы, поэтому он участвует в проекте, но не пишет для него код, эта задача была исключением.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[49]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.04.11 20:06
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> AN>Да, дядя препроцессор.


s>> Жесть

AN>Всегда интересовал перевод этого слова, хотя бы на русский.
Жестоко (по отношению к препроцессору). Шутка. Так это вы нам показали код еще и без #ifdef-ов и [Conditional]-ов? Т.е. поработали за препроцессор?

s>> Зря, это не враппер. Это абстракция. Враппером будет реализация этой абстракции.

AN>Интерфейс без реализации в данном случае никак не поможет, но по крайней мере теперь я понимаю, что вы называете абстракцией.
не я один. Удивлен, что не было понимания.

s>> И не требуется. Для того абстракция и вводится, что бы не писать ILog.WriteLine, что по сути эквивалентно Console.WriteLine.

AN>В итоге все равно нужен синглетон или статик.
Нет, можно и без них, через передачу реализации.
Классический сигнлетон в этом плане вряд ли лучше Console.WriteLine. А глобальные изменяемые состояния приносят проблемы, в том числе при тестировании.

s>> А сразу проверку с возвратом нельзя было сделать? Очень неочевидна логика метода.

AN>Так из за логики метод и попал на "доску почета"
ясно

s>> AN>ref-ы — чтобы здесь меньше строк писать, да и указывают они на параметр который функция может модифицировать.

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

s>> AN>Если обнаружены неправильные входные параметры, то сообщаем об ошибке.


s>> Сообщаем как?

AN>Как именно, абсолютно неважно, "каким либо образом". Эта тоже абстракция только не интерфейсная
Как это? с абстракцией работает конкретный код, потому он должен знать заранее, как к этой абстракции обращаться.

s>> Допустимо ли значение параметра 0 при отсутствии ошибки?

AN>Да, это ведь просто "врезка в трубу". Функция может здесь быть, а может и нет.
Я не понимаю, что такое "врезка в трубу". И если функци здесь может не быть, то значит ее и не должно быть.
А судя по всему, стояла задача изменить поведение функции, в коде которой кто-то не захотел разбираться по каким-то причинам, и вклинился в нее "малой кровью". Практически очевидно что изменение требований произошло после написания этой функции. А вы говорите, что нет повода к изменениям...

s>> Как узнать, что именно было обнаружено неправильного во входных данных?

AN>Для чего?
что бы в другой раз сделать правильно.
Но я походу понял что к чему. Обсуждаемая функция была просто вхачена в вызывающую что бы модифицировать состояния локальных переменных, дабы изменить поведение не переделывая логику.

s>> Разве нельзя переопределить вывод в файл на диске только для чтения? Или пользователь ССЗБ?

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

s>> Для того что бы его проигнорировать, надо ввести либо абстракцию, либо try/catch-ить все вызовы WriteLine. Ни того ни другого желания я у вас не обнаружил. Так что походу игнорирование — это просто забивание на исключения.

AN>А вы много видели программ с абстракцией или try/catch на console?
Достаточно, тем более что есть абстракция из коробки. См. Trace и TraceListener. Правда штатный TextWriterTraceListener не ловит исключения TextWriter-а. Что в принципе верно, т.к. он не знает, что с ними делать. Но это легко исправить, когда есть конкретные требования по этому поводу, подсунув специального наследника.

s>> Командная работа очень затруднена когда на команду одна думалка, компетентная разбираться в вопросах такого уровня. Хуже только когда их больше одной и у них разные мнения на этот счет.

AN>Во первых, думалка не думает о всех мелочах.
Потому я бы не стал выносить подобный вопрос на повестку, и максимум — решил бы его с кем-нибудь в рабочем порядке.
AN>А во вторых, две разных думалки это вообще замечательно, когда между ними нет личных конфликтов, а только рабочие. Рождаются очень интересные идеи.
А еще более интересные умирают.

s>> AN>Исторически данная функция изначально имела исключительно лишь входные данные, одним из которых был параметр для вывода дополнительного символа. Все остальные параметры ей были не нужны и были сделаны "на вырост". Если параметр для вывода был в норме то выводился всего лишь дополнительный символ.

s>> AN>Человеку разрешили менять только данную функцию, не меняя поведение остального кода.

s>> Интересно, сколько платят этому человеку?

AN>Сколько кому платят знает только бухгалтерия.
AN>Просто каждого человека нужно использовать там где он больше всего приносит пользы, поэтому он участвует в проекте, но не пишет для него код, эта задача была исключением.
Интерес мой больше к позиции конторы. Держать человека, которому доверяет историческую функцию и ничего более.
Re[50]: Как не надо писать код
От: AlexNek  
Дата: 26.04.11 21:33
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> AN>Да, дядя препроцессор.


s> s>> Жесть


s> AN>Всегда интересовал перевод этого слова, хотя бы на русский.


s> Жестоко (по отношению к препроцессору). Шутка.

Ага то то я по другому переводил

s> Так это вы нам показали код еще и без #ifdef-ов и [Conditional]-ов? Т.е. поработали за препроцессор?

Не а данная функция был просто скопирована из кода.

s> s>> Зря, это не враппер. Это абстракция. Враппером будет реализация этой абстракции.


s> AN>Интерфейс без реализации в данном случае никак не поможет, но по крайней мере теперь я понимаю, что вы называете абстракцией.


s> не я один. Удивлен, что не было понимания.

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

s> s>> И не требуется. Для того абстракция и вводится, что бы не писать ILog.WriteLine, что по сути эквивалентно Console.WriteLine.


s> AN>В итоге все равно нужен синглетон или статик.


s> Нет, можно и без них, через передачу реализации.

Странно как то себе это представляю передать на "10-й уровень".

s> s>> AN>ref-ы — чтобы здесь меньше строк писать, да и указывают они на параметр который функция может модифицировать.


s> знаю для чего нужны рефы, но предпочитаю не использовать их пока не занят результат функции. Да и когда занят порой предпочту создать новый тип для возврата.

Ну я к ним отношусь не столь настороженно, могут быть конечно побочные эффекты.
Да и в данном случае это была более минимальная переделка.

s> s>> AN>Если обнаружены неправильные входные параметры, то сообщаем об ошибке.


s> s>> Сообщаем как?


s> AN>Как именно, абсолютно неважно, "каким либо образом". Эта тоже абстракция только не интерфейсная


s> Как это? с абстракцией работает конкретный код, потому он должен знать заранее, как к этой абстракции обращаться.

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

s> s>> Допустимо ли значение параметра 0 при отсутствии ошибки?


s> AN>Да, это ведь просто "врезка в трубу". Функция может здесь быть, а может и нет.


s> Я не понимаю, что такое "врезка в трубу". И если функци здесь может не быть, то значит ее и не должно быть.

Ну это я люблю различные аналогии. Предположим, у нас есть труба по которой течет вода. Нужно поток как то регулировать/измерять/ чего добавлять. Для этого в подходящем месте в трубе делается разрез (точнее два) и вырезанная часть заменяется требуемой. Вот этот процесс и называется "врезкой в трубу" (не гарантирую правильность с точки зрения водопроводчика или сантехника ). Главное что врезка не должна кардинально менять состояние потока, в идеальном случае она должна быть незаметна, как прослушка на телефонной линии.
s> А судя по всему, стояла задача изменить поведение функции, в коде которой кто-то не захотел разбираться по каким-то причинам, и вклинился в нее "малой кровью". Практически очевидно что изменение требований произошло после написания этой функции. А вы говорите, что нет повода к изменениям...
Здесь было не совсем так, функция как раз то реализовывала запланированный интерфейс, только он планировался и работал немного по другому. А именно, функция либо выводила в поток через делегат специальный префикс либо другая реализация была "пустой". То есть либо "функция есть" либо "нет". Иначе говоря нужно было или передавать данные как есть или добавлять префикс. Но после выяснилось, что такая
реализация при определенных условиях дает недопустимую временную диаграмму и префикс необходимо передавать одновременно вместе с данными
s> s>> Как узнать, что именно было обнаружено неправильного во входных данных?

s> AN>Для чего?


s> что бы в другой раз сделать правильно.

s> Но я походу понял что к чему. Обсуждаемая функция была просто вхачена в вызывающую что бы модифицировать состояния локальных переменных, дабы изменить поведение не переделывая логику.
В данном случае верна только последняя фраза.

s> s>> Разве нельзя переопределить вывод в файл на диске только для чтения? Или пользователь ССЗБ?


s> AN>Ну можно вообще комп не включать и спрашивать почему прога не работает.

s> AN>Вывод в файл — это основная функция, если она не работает, то тут как раз и нужно как то сообщить о проблемах.

s> s>> Для того что бы его проигнорировать, надо ввести либо абстракцию, либо try/catch-ить все вызовы WriteLine. Ни того ни другого желания я у вас не обнаружил. Так что походу игнорирование — это просто забивание на исключения.


s> AN>А вы много видели программ с абстракцией или try/catch на console?


s> Достаточно, тем более что есть абстракция из коробки. См. Trace и TraceListener.

Вроде речь шла именно о Console. Мне лично еще ни разу не попадался консольный вывод с try/catch.

s> s>> Командная работа очень затруднена когда на команду одна думалка, компетентная разбираться в вопросах такого уровня. Хуже только когда их больше одной и у них разные мнения на этот счет.


s> AN>Во первых, думалка не думает о всех мелочах.


s> Потому я бы не стал выносить подобный вопрос на повестку, и максимум — решил бы его с кем-нибудь в рабочем порядке.

По поводу функции или по поводу использования исключений?
Функция уже давно исправлена, а модуль "заморожен".

s> AN>А во вторых, две разных думалки это вообще замечательно, когда между ними нет личных конфликтов, а только рабочие. Рождаются очень интересные идеи.


s> А еще более интересные умирают.

Пока мне такой ситуации не попадалось.

s> Интерес мой больше к позиции конторы. Держать человека, которому доверяет историческую функцию и ничего более.

Я показал только то что он сделал неудовлетворительно, но есть масса других вещей которые он делает довольно неплохо. Ну и позиция конторы довольно либеральная. Действительно бесполезного человека, даже если он каким то образом туда прорвется, безусловно держать не будут. Но если человеку тяжело дается одна работа, но зато хорошо получается другая, дают ту работу, которая получается лучше.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[51]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.04.11 10:27
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> AN>Интерфейс без реализации в данном случае никак не поможет, но по крайней мереhttp://www.rsdn.ru/forum/NewMsg.aspx?mid=4250449#
Автор: AlexNek
Дата: 27.04.11
теперь я понимаю, что вы называете абстракцией.


s>> не я один. Удивлен, что не было понимания.

AN>Не хочу делать предположений, но мне данное значение "абстракция" встречать еще не приходилось.
встречайте. Так же здесь и, например, здесь.

s>> AN>В итоге все равно нужен синглетон или статик.


s>> Нет, можно и без них, через передачу реализации.

AN>Странно как то себе это представляю передать на "10-й уровень".
Вы же не передаете компарер с 1-го на 10-ый уровень? Так же и тут. Непосредственно вызывающий код может указать вызываемому конкретную реализацию. Но при необходимости можно и на 10-ый передать, используя IoC контейнеры.

s>> Как это? с абстракцией работает конкретный код, потому он должен знать заранее, как к этой абстракции обращаться.

AN>Вот именно это я лично называю абстракцией. В нашем примере это должно быть неважно будет ли это проверка конкретного значения кода ошибки или ловля эксепшина. Есть способ для сообщения об ошибке и есть способ для ее "детектирования".
Важное отличие тут в том, что вы не скрыли реализацию проверки значения за абстракцией, а просто не указали его. Таким образом, невозможно подменить способ обработки конкретного значения, подменяя реализацию, если в одной реализации он делается через исключение, а в другой — иначе.

s>> Достаточно, тем более что есть абстракция из коробки. См. Trace и TraceListener.

AN>Вроде речь шла именно о Console. Мне лично еще ни разу не попадался консольный вывод с try/catch.
Так TraceListener имеет наследника ConsoleTraceListener, который и сливает вывод в консоль. Таким образом это абстракция над выводом сообщений вообще, с реализацией из коробки для вывода сообщений в консоль в том числе.
AN>Мне лично еще ни разу не попадался консольный вывод с try/catch.
Это не важно, важно что вы собрались гарантировать продолжение вычислений при исключениях в Console.WriteLine и средств кроме try/catch, для этого нет. использование обертки позволяет не оборачивать try/catch каждый вызов, а абстракция позволяет гибко указывать любую обертку, в том числе более интересную, чем предоставляющую вывод в консоль.

AN>По поводу функции или по поводу использования исключений?

AN>Функция уже давно исправлена, а модуль "заморожен".
Угу, табу на изменения до очередной "врезки" в трубу. Но судьба той функции меня вообще не занимает, в отличии от ваших убеждений в том, что в ней все путем.

AN>Я показал только то что он сделал неудовлетворительно, но есть масса других вещей которые он делает довольно неплохо. Ну и позиция конторы довольно либеральная. Действительно бесполезного человека, даже если он каким то образом туда прорвется, безусловно держать не будут. Но если человеку тяжело дается одна работа, но зато хорошо получается другая, дают ту работу, которая получается лучше.

Тогда я спокоен и за человека и за контору. Потому как если бы было бы иначе — то держать человека, думать что бы ему разрешить что бы он что-нибудь не сломал, и платить ему за это деньги — было бы очень фигово. Но я знаю бюджетную контору, где 60% сотрудников в таком положении.
Re[52]: Как не надо писать код
От: AlexNek  
Дата: 27.04.11 13:21
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> AN>Интерфейс без реализации в данном случае никак не поможет, но по крайней мереhttp://www.rsdn.ru/forum/NewMsg.aspx?mid=4250449#
Автор: AlexNek
Дата: 27.04.11
теперь я понимаю, что вы называете абстракцией.


s> s>> не я один. Удивлен, что не было понимания.


s> AN>Не хочу делать предположений, но мне данное значение "абстракция" встречать еще не приходилось.


s> встречайте. Так же здесь и, например, здесь.

Две первых ссылки одинаковые, но там написано именно так, как и ожидалось
Как интерпретировать "Выделять абстракцию" в "использование интерфейсов/абстрактных функций" автоматом я не знаю.
Хотя вот попались русские фразы: "Оба типа модулей должны зависеть от абстракций", "Абстракции не должны зависеть от деталей", которые я бы просто не смог бы понять без контекста.

s> s>> AN>В итоге все равно нужен синглетон или статик.


s> s>> Нет, можно и без них, через передачу реализации.


s> AN>Странно как то себе это представляю передать на "10-й уровень".


s> Вы же не передаете компарер с 1-го на 10-ый уровень? Так же и тут.

А откуда вы знаете какой компарер захотел пользователь?
s> Непосредственно вызывающий код может указать вызываемому конкретную реализацию. Но при необходимости можно и на 10-ый передать, используя IoC контейнеры.
Ну и насколько это будет удобнее одной строки Console.WriteLine()?
И контейнеры волшебным образом знают все общие данные?

s> s>> Как это? с абстракцией работает конкретный код, потому он должен знать заранее, как к этой абстракции обращаться.


s> AN>Вот именно это я лично называю абстракцией. В нашем примере это должно быть неважно будет ли это проверка конкретного значения кода ошибки или ловля эксепшина. Есть способ для сообщения об ошибке и есть способ для ее "детектирования".


s> Важное отличие тут в том, что вы не скрыли реализацию проверки значения за абстракцией, а просто не указали его. Таким образом, невозможно подменить способ обработки конкретного значения, подменяя реализацию, если в одной реализации он делается через исключение, а в другой — иначе.

Так а конкретика на данном уровне и не интересует, конкретика важна будет при реализации.
Это типа аналог "Black box".

s> s>> Достаточно, тем более что есть абстракция из коробки. См. Trace и TraceListener.


s> AN>Вроде речь шла именно о Console. Мне лично еще ни разу не попадался консольный вывод с try/catch.


s> Так TraceListener имеет наследника ConsoleTraceListener, который и сливает вывод в консоль. Таким образом это абстракция над выводом сообщений вообще, с реализацией из коробки для вывода сообщений в консоль в том числе.

Имелось в виду Console.WriteLine c try/catch

s> AN>Мне лично еще ни разу не попадался консольный вывод с try/catch.


s> Это не важно, важно что вы собрались гарантировать продолжение вычислений при исключениях в Console.WriteLine и средств кроме try/catch, для этого нет. использование обертки позволяет не оборачивать try/catch каждый вызов, а абстракция позволяет гибко указывать любую обертку, в том числе более интересную, чем предоставляющую вывод в консоль.


Зачем усложнять простые вещи? Да для общего принципа вывода на консоль это все совершенно верно. Но в конкретном месте гораздо проще было бы использовать просто Console.WriteLine без всяких исключений.

s> AN>По поводу функции или по поводу использования исключений?

s> AN>Функция уже давно исправлена, а модуль "заморожен".

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

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

s> AN>Я показал только то что он сделал неудовлетворительно, но есть масса других вещей которые он делает довольно неплохо. Ну и позиция конторы довольно либеральная. Действительно бесполезного человека, даже если он каким то образом туда прорвется, безусловно держать не будут. Но если человеку тяжело дается одна работа, но зато хорошо получается другая, дают ту работу, которая получается лучше.


s> Тогда я спокоен и за человека и за контору. Потому как если бы было бы иначе — то держать человека, думать что бы ему разрешить что бы он что-нибудь не сломал, и платить ему за это деньги — было бы очень фигово. Но я знаю бюджетную контору, где 60% сотрудников в таком положении.

Ну это как бы несколько другое. Исправленная функция делала именно то, что требовалось, не больше и не меньше. А то что я глянул во внутрь — это скорее моя проблема Скажем иначе, в теме которой он занимается, он считается экспертом, и любые вопросы идут к нему. Он же и нашел, весьма быстро, в чем заключалась проблема.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re: Как не надо писать код
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 27.04.11 13:50
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Что то часто мне стал попадаться код в который сразу не врубишься, при этом код делает свою задачу правильно. Предлагаю постить сюда ваши образчики и комментарии.


AN>Интересно сколько времени вам понадобилось, что бы понять как функция точно работает?


За 10 секунд получилось следующее: функция берет параметр buffer, сдвигает первые bufferLength его на единицу вправо с обрезанием последнего символа и добавлением PREFIX в начало. Если buffer пустой, то считается, что он заполнен нулями
Re[53]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.04.11 14:14
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


s>> встречайте. Так же здесь и, например, здесь.

AN>Две первых ссылки одинаковые, но там написано именно так, как и ожидалось
Первая ссылка на общую статью, вторая на ее частный раздел
AN>Как интерпретировать "Выделять абстракцию" в "использование интерфейсов/абстрактных функций" автоматом я не знаю.
Абстрактный метод имеет непосредственную связь с абстракцией. А интерфейс это лишь совокупность абстрактных методов. Делегат тоже достаточно абстрактен для употребления его в роли абстракции от метода, на который он ссылается.
AN>Хотя вот попались русские фразы: "Оба типа модулей должны зависеть от абстракций", "Абстракции не должны зависеть от деталей", которые я бы просто не смог бы понять без контекста.
В определенном контексте они имеют смысл, и этот контекст можно ассоциировать с этими фразами, но понимать их вне контекста не нужно.

s>> Вы же не передаете компарер с 1-го на 10-ый уровень? Так же и тут.

AN>А откуда вы знаете какой компарер захотел пользователь?
Пользователь указал этот компарер предусмотренным способом. Если такого способа нет — значит не удастся узнать, как хочет пользователь сравнивать значения.

s>> Непосредственно вызывающий код может указать вызываемому конкретную реализацию. Но при необходимости можно и на 10-ый передать, используя IoC контейнеры.

AN>Ну и насколько это будет удобнее одной строки Console.WriteLine()?
Это зависит от намерений. Я уже упоминал о том, что при необходимости обеспечить выполнение кода, невзирая на исключения, которые могут (а могут и не) высыпать из WriteLine, нет другого способа кроме как обернуть вызов в try/catch (уже не одна строка с Console.WriteLine()).
Т.е. варианты следующие:
а) забить и писать Console.WriteLine
б) обернуть try/catch-ем каждый вызов
в) написать обертку с try/catch
в1) обеспечить гибкость передачи обертки через абстракцию (это все-таки не самостоятельный вариант, а лишь способ указания конкретной обертки)
Все варианты кроме а) решают задачу. Вариант а) задачу не решает, но очень удобен. Почему его можно предпочесть — вероятность вылета исключения из WriteLine довольно низка и ей можно принебречь, что все и делают. Да и я тоже, когда не решаю задачу гарантированного продолжения выполнения кода, невзирая на исключения из Console.WriteLine()

AN>И контейнеры волшебным образом знают все общие данные?

Зависит от конкретного контейнера. Есть достаточно волшебные.

s>> Важное отличие тут в том, что вы не скрыли реализацию проверки значения за абстракцией, а просто не указали его. Таким образом, невозможно подменить способ обработки конкретного значения, подменяя реализацию, если в одной реализации он делается через исключение, а в другой — иначе.

AN>Так а конкретика на данном уровне и не интересует, конкретика важна будет при реализации.
Так это не абстракция, а просто опущенные детали.
AN>Это типа аналог "Black box".
Интерфейс взаимодействия с "Black box" должен быть достаточно "White", что бы BB предоставлял некий выход. Если мы не знаем что будет на выходе, то это не "Black box", а фактически "hole", за тем исключением что из Black hole ничего не вылетает обратно, кроме какого-то там теоретического излучения, которое никто не видел.

AN>Зачем усложнять простые вещи? Да для общего принципа вывода на консоль это все совершенно верно. Но в конкретном месте гораздо проще было бы использовать просто Console.WriteLine без всяких исключений.

А кто говорил о задаче гарантирования продолжения невзирая на изсключения из WriteLine?

AN>Я понимаю, что вы считаете данный подход в корне неверным. Я же только хочу сказать что не обязательно следует все мести под одну метлу.

AN>Вот сделал я допустим, супер пупер код который можно и там применить, и там и еще где то. Если нужно А получите А, если нужно Б получите Б. И все хорошо и все работает. Но вот чтобы во всем разобраться другому человеку ему нужно раз пять читать документацию.
AN>А если сделать тоже самое, но для конкретной задачи и для конкретного применения, другой человек без всякой документации сразу все поймет.
Во-первых, нужно выполнять задачу, если она все-таки стоит (об игноре исключений из WriteLine).
Во-вторых, в использовании принципов программирования не стоит ориентироваться на людей, которые их не знают и не понимают. Точнее не так.
Для начала все же лучше оценить, оправдывает ли цель средства. Если манипулирование абстракциями на таком уровне является проблемой для команды, то ну ее нафик, эту абстракцию. А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.

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

Хорошо. А игнор исключений консоли — это все же не проблема. Точнее она не стоит остро и маловероятно что встанет.
Re[2]: Как не надо писать код
От: AlexNek  
Дата: 27.04.11 14:56
Оценка:
Здравствуйте, Mystic, Вы писали:

M> AN>Что то часто мне стал попадаться код в который сразу не врубишься, при этом код делает свою задачу правильно. Предлагаю постить сюда ваши образчики и комментарии.


M> AN>Интересно сколько времени вам понадобилось, что бы понять как функция точно работает?


M> За 10 секунд получилось следующее: функция берет параметр buffer, сдвигает первые bufferLength его на единицу вправо с обрезанием последнего символа и добавлением PREFIX в начало. Если buffer пустой, то считается, что он заполнен нулями

А откуда появилась информация об обрезании?
И что именно проверяется перед началом?
Какие действия предпринимаются для неправильных данных? Верны они или нет?
Вопросов можно еще найти довольно много и ответ во многих случаях нужно искать, а не "увидеть"
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[54]: Как не надо писать код
От: AlexNek  
Дата: 27.04.11 16:01
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> встречайте. Так же здесь и, например, здесь.


s> AN>Две первых ссылки одинаковые, но там написано именно так, как и ожидалось


s> Первая ссылка на общую статью, вторая на ее частный раздел

Сорри, не заметил.
s> AN>Как интерпретировать "Выделять абстракцию" в "использование интерфейсов/абстрактных функций" автоматом я не знаю.

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

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

s> AN>Хотя вот попались русские фразы: "Оба типа модулей должны зависеть от абстракций", "Абстракции не должны зависеть от деталей", которые я бы просто не смог бы понять без контекста.


s> В определенном контексте они имеют смысл, и этот контекст можно ассоциировать с этими фразами, но понимать их вне контекста не нужно.

Ну вот примерно так и получилось.

s> s>> Вы же не передаете компарер с 1-го на 10-ый уровень? Так же и тут.


s> AN>А откуда вы знаете какой компарер захотел пользователь?


s> Пользователь указал этот компарер предусмотренным способом. Если такого способа нет — значит не удастся узнать, как хочет пользователь сравнивать значения.

Тода возникает вопрос как передать этот способ?

s> s>> Непосредственно вызывающий код может указать вызываемому конкретную реализацию. Но при необходимости можно и на 10-ый передать, используя IoC контейнеры.


s> AN>Ну и насколько это будет удобнее одной строки Console.WriteLine()?


s> Это зависит от намерений. Я уже упоминал о том, что при необходимости обеспечить выполнение кода, невзирая на исключения, которые могут (а могут и не) высыпать из WriteLine, нет другого способа кроме как обернуть вызов в try/catch (уже не одна строка с Console.WriteLine()).

s> Т.е. варианты следующие:
s> а) забить и писать Console.WriteLine
s> б) обернуть try/catch-ем каждый вызов
s> в) написать обертку с try/catch
s> в1) обеспечить гибкость передачи обертки через абстракцию (это все-таки не самостоятельный вариант, а лишь способ указания конкретной обертки)
s> Все варианты кроме а) решают задачу. Вариант а) задачу не решает, но очень удобен. Почему его можно предпочесть — вероятность вылета исключения из WriteLine довольно низка и ей можно принебречь, что все и делают. Да и я тоже, когда не решаю задачу гарантированного продолжения выполнения кода, невзирая на исключения из Console.WriteLine()
Есть еще теоретический вариант а1 Console.WriteLine не дает исключений.

s> AN>И контейнеры волшебным образом знают все общие данные?


s> Зависит от конкретного контейнера. Есть достаточно волшебные.

В сказки я не верю еще с детства.

s> s>> Важное отличие тут в том, что вы не скрыли реализацию проверки значения за абстракцией, а просто не указали его. Таким образом, невозможно подменить способ обработки конкретного значения, подменяя реализацию, если в одной реализации он делается через исключение, а в другой — иначе.


s> AN>Так а конкретика на данном уровне и не интересует, конкретика важна будет при реализации.


s> Так это не абстракция, а просто опущенные детали.

В моем случае камень — это абстракция скульптуры

s> AN>Это типа аналог "Black box".


s> Интерфейс взаимодействия с "Black box" должен быть достаточно "White", что бы BB предоставлял некий выход. Если мы не знаем что будет на выходе, то это не "Black box", а фактически "hole", за тем исключением что из Black hole ничего не вылетает обратно, кроме какого-то там теоретического излучения, которое никто не видел.

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

s> AN>Зачем усложнять простые вещи? Да для общего принципа вывода на консоль это все совершенно верно. Но в конкретном месте гораздо проще было бы использовать просто Console.WriteLine без всяких исключений.


s> А кто говорил о задаче гарантирования продолжения невзирая на изсключения из WriteLine?

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

s> AN>Я понимаю, что вы считаете данный подход в корне неверным. Я же только хочу сказать что не обязательно следует все мести под одну метлу.

s> AN>Вот сделал я допустим, супер пупер код который можно и там применить, и там и еще где то. Если нужно А получите А, если нужно Б получите Б. И все хорошо и все работает. Но вот чтобы во всем разобраться другому человеку ему нужно раз пять читать документацию.
s> AN>А если сделать тоже самое, но для конкретной задачи и для конкретного применения, другой человек без всякой документации сразу все поймет.

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

s> Во-вторых, в использовании принципов программирования не стоит ориентироваться на людей, которые их не знают и не понимают. Точнее не так.
s> Для начала все же лучше оценить, оправдывает ли цель средства.

s> Если манипулирование абстракциями на таком уровне является проблемой для команды, то ну ее нафик, эту абстракцию.

Дело не в конкретной проблеме, а в общем подходе. И дело, в основном, упирается во время.
s> А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.
Сегодня она одна, завтра совсем другая. Главный принцип "не выпендриваться".
Допустим, я знаю как мне написать "данный код" в 5 строк, но что бы в них разобраться и исправить нужно полчаса (даже и мне через пару лет). Поэтому лучше написать код в 20 строк, но который будет достаточно прозрачен.
Либо вот человек нашел/придумал новый клевый паттерн который позволяет работать с Х различными источниками. Хрен с ним что у нас только один источник, но вдруг когда будет много. Все казалось бы замечательно, только для изменений нужно вначале разобраться с паттерном, затем с кодом, и затем догадаться, где правильно будет изменять. Так, что дело далеко не в уровне подготовки команды.

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


s> Хорошо. А игнор исключений консоли — это все же не проблема. Точнее она не стоит остро и маловероятно что встанет.

Это просто был примерчик для сравнения вариантов.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[55]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.04.11 16:54
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, samius, Вы писали:


AN>Тексты на английском вполне понятны даже если читать отдельные предложения, чего я не могу сказать о подобных текстах на русском (хотя и звучит немного странно)

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

s>> Все варианты кроме а) решают задачу. Вариант а) задачу не решает, но очень удобен. Почему его можно предпочесть — вероятность вылета исключения из WriteLine довольно низка и ей можно принебречь, что все и делают. Да и я тоже, когда не решаю задачу гарантированного продолжения выполнения кода, невзирая на исключения из Console.WriteLine()

AN>Есть еще теоретический вариант а1 Console.WriteLine не дает исключений.
Мы совершенно точно знаем что он дает исключения. Вопрос лишь в том, на сколько серьезно мы относимся к обстоятельствам, при которых они возбуждаются, что бы принять решения об обработке исключений при обращении к консоли. Но считать что их там нет не можем.

s>> Зависит от конкретного контейнера. Есть достаточно волшебные.

AN>В сказки я не верю еще с детства.
А я и не говорю что это сказочный инструмент. Как и многие другие, он не только решает проблемы, но и создает их. И для его использования нужно понимание, которое не приходит от того что кто-то на форуме упомянул этот инструмент.

s>> Так это не абстракция, а просто опущенные детали.

AN>В моем случае камень — это абстракция скульптуры
В почках?

AN>Не понимаю для чего нужна конкретика? Есть некий признак указывающий на ошибочное состояние входных данных его нужно проанализировать и сделать определенные действия.

Конкретика здесь не нужна. Я лишь говорю о том, что неуточненные детали не есть абстракция.

s>> А кто говорил о задаче гарантирования продолжения невзирая на изсключения из WriteLine?

AN>Это как раз и есть два разных варианта действий. Вы говорите об использовании исключений всегда, я же говорю, что иногда удобнее использовать варианты без них.
В случае WriteLine нет вариантов без исключений. Вне зависимости от степени удобства, при определенных обстоятельствах исключения возбудятся. Наша воля лишь в том, обрабатывать их как-то или нет при написании кода. Я не настаиваю на том что их нужно обрабатывать в данном случае. Но тогда игнорировать их не получится, т.к. при возбуждении исключения выполнение кода будет прервано.

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

s>> Во-вторых, в использовании принципов программирования не стоит ориентироваться на людей, которые их не знают и не понимают. Точнее не так.
s>> Для начала все же лучше оценить, оправдывает ли цель средства.

s>> Если манипулирование абстракциями на таком уровне является проблемой для команды, то ну ее нафик, эту абстракцию.

AN>Дело не в конкретной проблеме, а в общем подходе. И дело, в основном, упирается во время.
Нечего возразить

s>> А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.

AN>Сегодня она одна, завтра совсем другая. Главный принцип "не выпендриваться".
Выполнить задачу

AN>Допустим, я знаю как мне написать "данный код" в 5 строк, но что бы в них разобраться и исправить нужно полчаса (даже и мне через пару лет). Поэтому лучше написать код в 20 строк, но который будет достаточно прозрачен.

Если он не будет достаточно гибок для использования в разных условиях, то он может размножиться до 100 строк при необходимости использования в разных условиях. DRY.
Опять же на примере WriteTransformation, были прежде всего вопросы, зачем тут 20 строк, а не 5? И разве они прозрачны?

AN>Либо вот человек нашел/придумал новый клевый паттерн который позволяет работать с Х различными источниками. Хрен с ним что у нас только один источник, но вдруг когда будет много. Все казалось бы замечательно, только для изменений нужно вначале разобраться с паттерном, затем с кодом, и затем догадаться, где правильно будет изменять. Так, что дело далеко не в уровне подготовки команды.

Дело в уровне. Если член команды знаком с паттерном (даже если не знаком с названием), ему не потребуется много времени на его понимание. Это как я скажу коллеге "цикл for" и он поймет, о чем речь, ему не надо будет изучать как работает этот цикл, понимать код, выдумывать как его изменять. Только другой уровень. Не слишком высокий. Этот уровень часто требуется при устройстве на работу. Достаточно часто, что бы о нем следовало иметь представление членам средней команды.

s>> Хорошо. А игнор исключений консоли — это все же не проблема. Точнее она не стоит остро и маловероятно что встанет.

AN>Это просто был примерчик для сравнения вариантов.
Ок, тогда мы его усугубим. Предположим (уверен, что такого не будет, но тем не менее), что код, который пишет в консоль о прогрессе вычислений, потребовалось изменить так, что бы он сегодня писал в консоль, при нажатой галочке отправлял на почту, а в некоторой фазе луны сохранял бы вывод в БД или отправлял бы веб сервису. Типичный пример на принцип открытия-закрытия (OCP). Будете из 20 строчек делать 100 что бы "не выпендриваться", или примените приемы, недоступные коллег(е|ам) по команде?
Re[56]: Как не надо писать код
От: AlexNek  
Дата: 27.04.11 20:10
Оценка:
Здравствуйте, samius, Вы писали:

s> AN>Здравствуйте, samius, Вы писали:


s> s>> Все варианты кроме а) решают задачу. Вариант а) задачу не решает, но очень удобен. Почему его можно предпочесть — вероятность вылета исключения из WriteLine довольно низка и ей можно принебречь, что все и делают. Да и я тоже, когда не решаю задачу гарантированного продолжения выполнения кода, невзирая на исключения из Console.WriteLine()


s> AN>Есть еще теоретический вариант а1 Console.WriteLine не дает исключений.


s> Мы совершенно точно знаем что он дает исключения. Вопрос лишь в том, на сколько серьезно мы относимся к обстоятельствам, при которых они возбуждаются, что бы принять решения об обработке исключений при обращении к консоли. Но считать что их там нет не можем.


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

s> s>> Зависит от конкретного контейнера. Есть достаточно волшебные.


s> AN>В сказки я не верю еще с детства.


s> А я и не говорю что это сказочный инструмент. Как и многие другие, он не только решает проблемы, но и создает их. И для его использования нужно понимание, которое не приходит от того что кто-то на форуме упомянул этот инструмент.


Была речь о "волшебстве", которое в итоге как то превращается в "глобальную переменную"

s> s>> Так это не абстракция, а просто опущенные детали.


s> AN>В моем случае камень — это абстракция скульптуры


s> В почках?

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

s> AN>Не понимаю для чего нужна конкретика? Есть некий признак указывающий на ошибочное состояние входных данных его нужно проанализировать и сделать определенные действия.


s> Конкретика здесь не нужна. Я лишь говорю о том, что неуточненные детали не есть абстракция.

Ну это смотря на каком уровне их рассматривать и для чего. Я никак не могу взять в толк для чего нужно опускаться еще ниже.

s> s>> А кто говорил о задаче гарантирования продолжения невзирая на изсключения из WriteLine?


s> AN>Это как раз и есть два разных варианта действий. Вы говорите об использовании исключений всегда, я же говорю, что иногда удобнее использовать варианты без них.


s> В случае WriteLine нет вариантов без исключений.

Но ничто не запрещает нам их представить.
s> Вне зависимости от степени удобства, при определенных обстоятельствах исключения возбудятся. Наша воля лишь в том, обрабатывать их как-то или нет при написании кода. Я не настаиваю на том что их нужно обрабатывать в данном случае. Но тогда игнорировать их не получится, т.к. при возбуждении исключения выполнение кода будет прервано.
Во, требования обработки исключений не стоит. Использовать WriteLine кто то еще, больше не будет. Тогда вопрос, а нафига они нам нужны в этом конкретном случае.

s> s>> А может стоит подтянуть команду? Все же это не ахти какой уровень владения программированием.


s> AN>Сегодня она одна, завтра совсем другая. Главный принцип "не выпендриваться".


s> Выполнить задачу


s> AN>Допустим, я знаю как мне написать "данный код" в 5 строк, но что бы в них разобраться и исправить нужно полчаса (даже и мне через пару лет). Поэтому лучше написать код в 20 строк, но который будет достаточно прозрачен.


s> Если он не будет достаточно гибок для использования в разных условиях, то он может размножиться до 100 строк при необходимости использования в разных условиях. DRY.

(Но...), как и вариантов может быть довольно много, решается строго индивидуально.
Но опять таки "Если он не будет достаточно гибок для использования в разных условиях". Здесь довольно часто нужен оптимальный компромисс. Почти все гибкое довольно сложное в какой либо проекции.

s> Опять же на примере WriteTransformation, были прежде всего вопросы, зачем тут 20 строк, а не 5? И разве они прозрачны?

Я уже повторял, что это не пример кода для подражания, а совсем наоборот.
Кстати, поначалу, вместе со скобками там и было 5 строк

s> AN>Либо вот человек нашел/придумал новый клевый паттерн который позволяет работать с Х различными источниками. Хрен с ним что у нас только один источник, но вдруг когда будет много. Все казалось бы замечательно, только для изменений нужно вначале разобраться с паттерном, затем с кодом, и затем догадаться, где правильно будет изменять. Так, что дело далеко не в уровне подготовки команды.


s> Дело в уровне. Если член команды знаком с паттерном (даже если не знаком с названием), ему не потребуется много времени на его понимание. Это как я скажу коллеге "цикл for" и он поймет, о чем речь, ему не надо будет изучать как работает этот цикл, понимать код, выдумывать как его изменять. Только другой уровень. Не слишком высокий. Этот уровень часто требуется при устройстве на работу. Достаточно часто, что бы о нем следовало иметь представление членам средней команды.

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

s> s>> Хорошо. А игнор исключений консоли — это все же не проблема. Точнее она не стоит остро и маловероятно что встанет.


s> AN>Это просто был примерчик для сравнения вариантов.


s> Ок, тогда мы его усугубим. Предположим (уверен, что такого не будет, но тем не менее), что код, который пишет в консоль о прогрессе вычислений, потребовалось изменить так, что бы он сегодня писал в консоль, при нажатой галочке отправлял на почту, а в некоторой фазе луны сохранял бы вывод в БД или отправлял бы веб сервису. Типичный пример на принцип открытия-закрытия (OCP). Будете из 20 строчек делать 100 что бы "не выпендриваться", или примените приемы, недоступные коллег(е|ам) по команде?

Однозначно сказать не могу, многое зависит от конкретной ситуации. Если работаю глубоко на "своем поле", на которое нехрен ходить, то вероятнее будут 20, если поле на пересечении или планируются частые изменения и эта сотня вполне адекватна, то вероятнее 100. А если решения равнозначны "по весу", то всегда более простое. Или если сотня будет иметь сильно много ограничений, то тогда 20.

Что из последнего помню. Есть у меня один "длинный" switch, раздражал он меня долго и придумал даже как он него избавится. Но потом сравнил решения и оставил как есть.
Когда на switch смотришь все понятно и нет вопросов. А так нужно думать, нафига то, нафига это, а как добавлять новую ветку и пр.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[2]: Как не надо писать код
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 28.04.11 02:00
Оценка:
Здравствуйте, Sinix, Вы писали:

S>За ref-ы, допущение того, что bufferLength может быть меньше 0, непроверку на переполнение — приговорить к пожизненному сопровождению своего кода.


Ну да — тут не всё так просто в общем случае. Например никто никогда не задумывался, почему Array.Length имеет тип int, а не uint (хотя на первый взгляд второй вариант логичнее)?
[КУ] оккупировала армия.
Re[3]: Как не надо писать код
От: Sinix  
Дата: 28.04.11 02:24
Оценка: 1 (1)
Здравствуйте, koandrew, Вы писали:

K>Ну да — тут не всё так просто в общем случае. Например никто никогда не задумывался, почему Array.Length имеет тип int, а не uint (хотя на первый взгляд второй вариант логичнее)?


1. warning CS3001: Argument type 'uint' is not CLS-compliant
2. а собсно зачем заводить массив, который займёт >2гб памяти? (берём крайний случай — с byte[]/bool[].) В типовой системе из-за фрагментации легко получить OutOfMemory даже на 200мб.
Re[4]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.04.11 03:15
Оценка: +2 :)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, koandrew, Вы писали:


K>>Ну да — тут не всё так просто в общем случае. Например никто никогда не задумывался, почему Array.Length имеет тип int, а не uint (хотя на первый взгляд второй вариант логичнее)?


S>1. warning CS3001: Argument type 'uint' is not CLS-compliant

S>2. а собсно зачем заводить массив, который займёт >2гб памяти? (берём крайний случай — с byte[]/bool[].) В типовой системе из-за фрагментации легко получить OutOfMemory даже на 200мб.

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

А на эту тему у меня есть свежий пример из собственной практики. Увидел ворнинг о сравнении знаковых и беззнаковых в следующем коде на C++:
for (int i = vector.size() - 1; i >= 0; i--)
     foo(vector[i]);

исправил на нечто вроде
for (size_t i = vector.size() - 1; i >= 0u; i--)
     foo(vector[i]);

и потом долго не мог связать срыв крыши у программы с этим изменением.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.