Автор Тема: Часто замечаю за собой  (Прочитано 30744 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Часто замечаю за собой
« : Январь 27, 2012, 05:12:40 am »
Предлагаю обсудить здесь тему отсюда: http://forum.oberoncore.ru/viewtopic.php?p=70068#p70068

По поводу нулевых указателей. Проблема частично языковая (нет в языке средств статического контроля). Но чаще всего это следствие дизайна. Компонент допускает "непроиниченность".  Или  задает протокол типа "get/set", делегируя на пользователя ответственность за то, что и когда туда выставляется и берется. Ошибиться становится легко.

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

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

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #1 : Январь 27, 2012, 05:34:13 pm »
По поводу нулевых указателей. Проблема частично языковая (нет в языке средств статического контроля). Но чаще всего это следствие дизайна. Компонент допускает "непроиниченность".  Или  задает протокол типа "get/set", делегируя на пользователя ответственность за то, что и когда туда выставляется и берется. Ошибиться становится легко.
Что имеется в виду под непроиниченностью? Непосредственно нулевой указатель?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #2 : Январь 27, 2012, 06:31:50 pm »
Что имеется в виду под непроиниченностью? Непосредственно нулевой указатель?

Нет, речь идет об уровне выше - компоненте и его дизайне. Попробую на примере:
converter = create_converter();
converter.set_source(source);
converter.set_destination(destination);
converter.run();

В данном случае дизайн компонента (converter) допускает, что его могут попросить что-то сконвертировать (вызвать run) не указав откуда и куда. В случае, если source и destination - объекты, получим обсуждаемое разыменование нулевого указателя. Мало того, в каждом методе этого компонента (если там будет что-то кроме run) - надо будет проверить (ASSERT), что source и destination не нулевые. Головная боль и писателю компонента, и пользователю.

Если переделать вот так:
converter = create_converter(source, destination);
converter.run();

То пользователю труднее ошибиться. Код проще, ошибок меньше, проверять указатели надо только один раз - в create_converter (пользователь, естественно, не имеет доступа к set_source/set_destination).

P.S. Существуют рекомендации для С++ (в том числе от самой M$) о том как полезно разносить создание объекта (конструктор) и его инициализацию (какой-нибудь Create). Архивредная "рекомендация" и антипаттерн.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #3 : Январь 28, 2012, 12:47:42 pm »
Ну да, я тоже такие многоступенчатые инициализации не люблю. И в простых случаях стараюсь передать все нужные данные в конструкторе. А то при отсутствии NIL непонятно, как объекты возвращать из прцедур : ).

DIzer

  • Гость
Re: Часто замечаю за собой
« Ответ #4 : Январь 28, 2012, 04:33:48 pm »
Данный дизайн (допускающий отложенную инициализацию) подразумевает возможное использования экземпляра класса в течении длительного времени(либо повторные использования экземпляра), если бизнес логика КОНЕЧНОГО приложения подразумевает частичное использование функциональности компонента и ДОПУСТИМО его небольшое время жизни - (в моей практике весьма частый случай)- я предпочитаю делать wrapperы в виде функций (компонента создается локально).

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #5 : Январь 28, 2012, 06:57:38 pm »
Данный дизайн (допускающий отложенную инициализацию) подразумевает возможное использования экземпляра класса в течении длительного времени(либо повторные использования экземпляра),

Это единственное разумное объяснение. Но даже в таком виде - это premature optimization. Со всеми описанными проблемами.

если бизнес логика КОНЕЧНОГО приложения подразумевает частичное использование функциональности компонента и ДОПУСТИМО его небольшое время жизни - (в моей практике весьма частый случай)- я предпочитаю делать wrapperы в виде функций (компонента создается локально).

Угу. Создание враппера как раз подтверждает, что оригинал задизайнен плохо. Компонент изначально должен быть с макимально простым и однозначным интерфейсом, недопускающим разных толкований и неоднозначностей.  А вот если нам нужна оптимизация - ничинаем коверкать дизайн.
« Последнее редактирование: Январь 28, 2012, 06:59:59 pm от vlad »

DIzer

  • Гость
Re: Часто замечаю за собой
« Ответ #6 : Январь 28, 2012, 07:59:54 pm »

Угу. Создание враппера как раз подтверждает, что оригинал задизайнен плохо. Компонент изначально должен быть с макимально простым и однозначным интерфейсом, недопускающим разных толкований и неоднозначностей.  А вот если нам нужна оптимизация - ничинаем коверкать дизайн.
Да нет, чаще всего это означает, что функциональность используемого компонента в КОНЕЧНОМ приложении - излишняя (это, с моей точки зрения, вполне допустимое "зло"). Нда, кстати - одно из немногих (в моей практике) применений замыканий - использование их именно в ПОДОБНЫХ ситуациях - они позволяют консервировать ресурсы программы (использовать один и тот же экземпляр БЕЗОПАСНО много раз в течении длительного времени). Мм все ожидал, что наши любители функциональщины приведут  пример в этом роде, ну ладно...

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #7 : Январь 28, 2012, 10:35:06 pm »
Да нет, чаще всего это означает, что функциональность используемого компонента в КОНЕЧНОМ приложении - излишняя (это, с моей точки зрения, вполне допустимое "зло").

Да, такой вариант, конечно, тоже может быть. И это не зло.

Нда, кстати - одно из немногих (в моей практике) применений замыканий - использование их именно в ПОДОБНЫХ ситуациях - они позволяют консервировать ресурсы программы (использовать один и тот же экземпляр БЕЗОПАСНО много раз в течении длительного времени). Мм все ожидал, что наши любители функциональщины приведут  пример в этом роде, ну ладно...

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #8 : Январь 30, 2012, 05:28:23 am »
Нда, кстати - одно из немногих (в моей практике) применений замыканий - использование их именно в ПОДОБНЫХ ситуациях - они позволяют консервировать ресурсы программы (использовать один и тот же экземпляр БЕЗОПАСНО много раз в течении длительного времени). Мм все ожидал, что наши любители функциональщины приведут  пример в этом роде, ну ладно...
Это что же, долгоживущий мутабельный объект? Это же зло с точки зрения ФП...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #9 : Январь 30, 2012, 09:24:54 am »
Это что же, долгоживущий мутабельный объект? Это же зло с точки зрения ФП...
С другой стороны, плодить на каждый чих новый объект - тоже зло.
Это противоречие довольно удачно решено в языке Clean. Там можно менять содержимое объекта и не отступать от ФП.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #10 : Январь 30, 2012, 09:49:53 am »
Это что же, долгоживущий мутабельный объект? Это же зло с точки зрения ФП...
С другой стороны, плодить на каждый чих новый объект - тоже зло.
Это противоречие довольно удачно решено в языке Clean. Там можно менять содержимое объекта и не отступать от ФП.
Трудно сказать -- удачно или нет. По отзывам, уникальные типы не так уж и удобны на практике...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DIzer

  • Гость
Re: Часто замечаю за собой
« Ответ #11 : Февраль 01, 2012, 10:38:29 am »

Это что же, долгоживущий мутабельный объект? Это же зло с точки зрения ФП...
А причем тут это? Я попытался сказать о "естественном" (с моей точки зрения) применении элементов ФЯП в контексте реальных "практических" случаев (обсуждаемых в этой ветке). И это использование (в противовес к точке зрения Алексея - о ненужности многословных лямбд и замыканий) не сводится к "сахару" ,т.е. формально может быть оправданием введения многословных "REFERENCE TO PROCEDURE" в ИЯП.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #12 : Февраль 24, 2012, 11:32:44 am »
Тем временем на оберонкоре просиходит забавное:

Цитата: Иван Кузьмицкий
Вспомнил ещё одну довольно шаблонную ошибку. Это отсутствие явной инициализации полей.

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

Цитата: Евгений Темиргалеев
Цитата: Илья Ермаков
Я для таких дел имел процедуру ZeroRec (имя, как в Дельфе) и ей зачищал записи до использования.
В качестве замечания: инициализация # зануление; ZeroRec, об которой речь, требует IMPORT SYTSTEM.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

DIzer

  • Гость
Re: Часто замечаю за собой
« Ответ #13 : Февраль 24, 2012, 11:53:50 am »
Насколько я понимаю, тут речь идет о процедуре на все случае жизни (работающей для произвольной записи) -  а что удивительного ? Хотя, лично я предпочитаю на каждый определенный тип записи иметь фабричную функцию - всех проблем не решает, но  пусть хоть  компилятор проверит наличие факта передачи значений ВСЕХ полей. А по поводу дефолтной  инициализации - так  с пол года назад у нас Игорем здесь на форуме был обмен мнениями...а еще раньше был comdiv со своими предложениями...
« Последнее редактирование: Февраль 24, 2012, 11:59:09 am от DIzer »

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Часто замечаю за собой
« Ответ #14 : Февраль 24, 2012, 12:00:02 pm »
Насколько я понимаю, тут речь идет о процедуре на все случае жизни (работающей для произвольной записи) -  а что удивительного ?
Изначально Вирт и компания предполагали SYSTEM использовать в не безопасных модулях не портабельных модулях. То есть, по сути, в Обероне если модуль импортирует SYSTEM, то это метка, что модуль не безопасный и, возможно, не портабельный.

Тут же предлагается импортировать SYSTEM для повышения безопасности модуля.

Таким образом, практически любой модуль будет импортировать SYSTEM. Что делает любой модуль потенциально опаснобезопасным. Стирается грань. Это не хорошо.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"