powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Праграмист, пешы красива!
98 сообщений из 98, показаны все 4 страниц
Праграмист, пешы красива!
    #34536829
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предлагаю на суд зрителей свой небольшой статьец по поводу стиля написания программного кода. Собственно, основа статьи была написана по просьбе руководителя проекта, в котором я некоторое время контрактил (в ответ на моё удивлённое "Ёёё, ну и наваяли! У них чё - зарплата от количества написанных строк зависила?"). Ну, написал первую версию статейки, а потом Остапа понесло...

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

Может, некоторые идеи покажутся супер-банальными (например, о разбиении скриптов на под-скрипты - вы можете подумать: ещё бы посоветовал зубы по утрам чистить...) - но, поверьте, я такое повидал, что лысина дыбом... Наболело...

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

Итак, гоу эхед: zuskin.com/coding_habits.htm
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34539094
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прочитал. Почти со всем согласен.
Но есть и замечания:

1) Передача параметров между объектами

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

Я использую следующий подход:
Допустим есть окно w_имя_окна, которому надо передать композитный параметр.
Тогда создаем невизуальный объект n_имя_окна_parm,
в котором объявляются все необходимые именно этому окну параметры.
Код: plaintext
1.
2.
3.
4.
w_имя_окна w
n_имя_окна_parm parm
parm = Create n_имя_окна_parm
....
OpenWithParm(w, parm)

Раньше я использовал вариацию на эту же тему:
В окне объявляется локальная структура, str_parm с теми же параметрами
Вызов окна тогда выглядит так:

Код: plaintext
1.
2.
3.
w_имя_окна w
w_имя_окна`str_parm parm
....
OpenWithParm(w, parm)

Однако структура не всегда удобна: в ней нельзя указать значения по умолчанию, и она всегда
передается по значению (копированием)


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

Но в качестве одного из примеров как технически можно записать такую проверку
было предложено следующее:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CHOOSE CASE TRUE
	CASE NOT THIS.of_validate1()

	CASE NOT THIS.of_validate2()

	CASE NOT THIS.of_validate3()

	CASE ELSE
		lb_ok = TRUE
END CHOOSE 

Во-первых этот код можно переписать более лаконично:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CHOOSE CASE FALSE
	CASE THIS.of_validate1()

	CASE THIS.of_validate2()

	CASE THIS.of_validate3()

	CASE ELSE
		lb_ok = TRUE
END CHOOSE 
Но все равно остается проблема: здесь используется побочный эффект
конструкции CHOOSE CASE - кейсы проверяются в порядке следования в коде.
Однако у меня совершенно нет уверенности что в будущем это сохранится.
И тогда при очередной миграции начнутся чудеса.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34543699
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЯ использую следующий подход:
Допустим есть окно w_имя_окна, которому надо передать композитный параметр.
Тогда создаем невизуальный объект n_имя_окна_parm,
в котором объявляются все необходимые именно этому окну параметры.Это то, что называется "стрейфорвард солюшн" - т.е. первое, что приходит в голову. Конечно, можно и этот подход осуществить, если неохота посидеть и подумать как облегчить весь последующий девелопмент, найдя универсальное (дженерик) решение, но с тем-же успехом можно отказаться от наследования и для каждого случая строить отдельный (специальный) объект. Дело в том, что аппликация, над которй я сейчас работаю по контракту, написана именно с помощью этого подхода - ох и приходится мудохаться... Во-первых, все PBLы просто наводнены вот такими классами, цель которых - просто передать параметры. Просто наводнение, фиг найдёшь среди них действительно нужный класс! Да уж лучше б создали один класс, содержащий все возможные в аппликации поля для передачи (сколько их - 50? 60?), если ради строгого контроля типов готовы на такое психическое напряжение... Во-вторых, многие скрипты содержат объявления десятков переменных вот таких типов, а потом в CHOOSE CASE решается какие из них инстантиировать. Вместо того чтоб иметь дело всегда с одним классом (или стринговой переменной, содержащей параметры через делимитр). Это уже не говоря о том, что для добавления параметра приходется чекаутить объект, изменять и чекинить обратно - вместо того, чтоб просто добавить строчку в скрипте (при множественности объектов передачи параметров эту строчку всё равно добавляешь). Что может быть проще, чем объявить во всех классах (естественно, на уровне предка) функции uf_key() и uf_get_key() которые соответственно генерируют и принимают аргумент (сохраняя в инстанс вариэйблз) в виде описанного в статье класса-почтальона или просто строки и заполняются девелоперпом в классах-потомках согласно бизнес-правилам? Так что предложенный Вами метод не был рекомендован специально, а не по неведению; более того, я написал целый абзац о его проблематичности, но убрал т.к. статью читают на моей нынешней работе и я не хочу чтоб они восприняли это как камень в свой огород.

Anatoly MoskovskyНо в качестве одного из примеров как технически можно записать такую проверку
было предложено следующее:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CHOOSE CASE TRUE
	CASE NOT THIS.of_validate1()

	CASE NOT THIS.of_validate2()

	CASE NOT THIS.of_validate3()

	CASE ELSE
		lb_ok = TRUE
END CHOOSE 

Во-первых этот код можно переписать более лаконично:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CHOOSE CASE FALSE
	CASE THIS.of_validate1()

	CASE THIS.of_validate2()

	CASE THIS.of_validate3()

	CASE ELSE
		lb_ok = TRUE
END CHOOSE 
Может, более лаконично, но, ИМХО, чуть менее "понимабельно" по сути. Впрочем, это мелочь.

Anatoly MoskovskyНо все равно остается проблема: здесь используется побочный эффект
конструкции CHOOSE CASE - кейсы проверяются в порядке следования в коде.
Однако у меня совершенно нет уверенности что в будущем это сохранится.
И тогда при очередной миграции начнутся чудеса.Пожалуй, этот момент с CHOOSE CASE можно вообще выкинуть из статьи, он непринципиален.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34543789
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я еще вот с этим не согласен:
Код: plaintext
1.
2.
3.
4.
5.
*** GOOD code: ***
DO WHILE TRUE
	ll_row = dw.GetNextModified(ll_row, Primary!)
	IF li_row <  1  THEN EXIT
	{code fragment}
LOOP
С классической точки зрения такой цикл надо описывать так:
Код: plaintext
1.
2.
3.
4.
5.
DO 
	ll_row = dw.GetNextModified(ll_row, Primary!)
	IF ll_row >=  1  THEN
		{code fragment}
	END IF
LOOP WHILE ll_row =  0 
....
Про создание первичных ключей. Ты перечислил несколько минусов натуральных ключей (все эти минусы можно отмести одним общим возражением - неправильно определено что является натуральным ключом). Но ты ни слова не сказал о минусах сурогатных ключей. А вот лично я их ненавижу. Да, они удобнее натуральных в случае если натуральный ключ надо поменять, но зато клиенту прийдется повозится чтобы создать этот самый сурогатный ключ. Хорошо если в БД есть встроенная система генерации (типа sequences в Oracle или @@identity в Sybase). А если нету? Как ты собираешься создавать номер для ключа в мультиклиентском приложении?
Натуральные ключи всегда лучше. Даже если ты вынужден передавать пять-восемь полей для идентификации одной записи - все равно это намного лучше чем работать с абстрактным числом. Хотя бы тем, что серверу БД прийдется вести только один индекс а не два. А это приводит к более быстрой работе всей базы.
.....
Про передачу параметров в окна.
А зачем вообще открывать окна с параметрами? Намного проще делать так:
Код: plaintext
1.
2.
Open(w_target)
w_target.of_SetKey('somekey', 'value')
w_target.of_SetKey('otherkey', 'othervalue')
Тогда ты сохранишь и читабельность кода и не понадобится заводить структур, и у тебя останется возможность открыть окно с неполным набором параметров. И в будущем, если понадобится добавить в w_target новый параметр, тебе не нужно будет заниматься перекомпиляцией всех объектов которые открывают данное окно (и используют структуру для передачи параметров)


---
http://www.rusug.ru] Портал русскоязычной группы пользователей Sybase
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34543939
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlА я еще вот с этим не согласен:
Код: plaintext
1.
2.
3.
4.
5.
*** GOOD code: ***
DO WHILE TRUE
	ll_row = dw.GetNextModified(ll_row, Primary!)
	IF li_row <  1  THEN EXIT
	{code fragment}
LOOP
С классической точки зрения такой цикл надо описывать так:
Код: plaintext
1.
2.
3.
4.
5.
DO 
	ll_row = dw.GetNextModified(ll_row, Primary!)
	IF ll_row >=  1  THEN
		{code fragment}
	END IF
LOOP WHILE ll_row =  0 
Я тоже так думал, начитавшись книжек в колледже. Но МНЕ удобней так, как я описАл - жизнь научила. Если {code fragment} сам по себе имеет инденты (табы), зачем усугублять? Если ты привык за годы карьеры иначе и не имеешь охоты "переключаться" - дык и не надо! Привычка - страшная сила, по себе знаю.

White OwlПро создание первичных ключей. Ты перечислил несколько минусов натуральных ключей (все эти минусы можно отмести одним общим возражением - неправильно определено что является натуральным ключом).Приведённое определение - не моё, и звучит очень просто: натуральный ключ - это такой первичный ключ (или кандидат), значения которого кроме уникальной идентификации записей таблицы имеют какой бы то ни было дополнительный смысл в реальной жизни.

White OwlНо ты ни слова не сказал о минусах сурогатных ключей. А вот лично я их ненавижу. Да, они удобнее натуральных в случае если натуральный ключ надо поменять, но зато клиенту прийдется повозится чтобы создать этот самый сурогатный ключ. Хорошо если в БД есть встроенная система генерации (типа sequences в Oracle или @@identity в Sybase). А если нету? Как ты собираешься создавать номер для ключа в мультиклиентском приложении?Даже в тех субэдэшках, что имеют внутренние средства генерации ключей, лучше ими не пользоваться (и в большинстве проектов, куда меня засылала партия, они и не использовались). Решение простое: имеется таблица, состоящая из двух полей: entity_name и next_value. Создал в системе новую сущность - загоняешь в таблицу запись для неё:

Код: plaintext
INSERT INTO tbl_ids (entity_name, next_value) VALUES ('emp_id',  1 );

И создаёшь хранимую процедуру или функцию которая принимает название сущности и возвращает следующее значение нумератора (доступ скриптов к таблице будет осуществляться ТОЛЬКО через неё); естественно, эта функция увеличивает next_value на единицу готовя почву для следующего вызова; даже более того - если запись для данной сущности ещё не существует, она её создаёт вышеназванным инсёртом (или генерирует ошибку, что, ИМХО, лучше - всё надо делать обдуманно). Этот способ (в отличие от неуправляемых оракловских сиквенсов) делает генерацию ключа частью транзакции (со всеми вытекающими для мультиклиентских приложений преимуществами). Да и зачем загружать систему кучей сиквенсов если можно иметь одну маленькую табличку? А сначала создавать запись с отоинкрементом, затем считывать новорожденное значение через @@identity - всё равно что ехать из Питера в Москву через Северный Полюс. Лучше разбить всё на этапы: сначала генерируешь нумератор в переменную, затем вставляешь везде, где надо в рамках данной транзакции (например, в первичный ключ таблицы-master и во внешние ключи таблиц-details). Именно так я собираеюсь создавать номер для ключа в мультиклиентском приложении. Лишь одно обидно: все эти умные идеи - не мои :-).

White OwlНатуральные ключи всегда лучше.В программировании (да и вообще в жинзи) вряд-ли есть вещи, которые ВСЕГДА лучше.

White OwlДаже если ты вынужден передавать пять-восемь полей для идентификации одной записи - все равно это намного лучше чем работать с абстрактным числом.А если 20-30 - это, по твоей логике, вааще кайф! Кстати, натуральный номер работника - такое-же абстрактное число (плюс куча всяких ограничений и возможных неприятных сюрпризов в будущем), просто оно уже существовало до создания записи в базе данных. Что будешь с этим делать, ненавистник суррогатных ключей?

White OwlХотя бы тем, что серверу БД прийдется вести только один индекс а не два. А это приводит к более быстрой работе всей базы.Зависит от многих обстоятельств. В некоторых ты прав (например, если до черта инсёртов и мало селектов). А кроме этого момента, ЧЕМ ИМЕННО естественные ключи лучше? Ты просто написал что ненавидишь суррогатные, что, согласись, не аргумент. Я не ищу спора - мне просто совершенно откровенно интересно что хорошего в том, что за все эти годы выпило у меня столько крови.

White OwlПро передачу параметров в окна.
А зачем вообще открывать окна с параметрами? Намного проще делать так:
Код: plaintext
1.
2.
Open(w_target)
w_target.of_SetKey('somekey', 'value')
w_target.of_SetKey('otherkey', 'othervalue')
Тогда ты сохранишь и читабельность кода и не понадобится заводить структур, и у тебя останется возможность открыть окно с неполным набором параметров. И в будущем, если понадобится добавить в w_target новый параметр, тебе не нужно будет заниматься перекомпиляцией всех объектов которые открывают данное окно (и используют структуру для передачи параметров)Речь шла вообще о передаче параметров между объектами, окно - просто пример. В твоём примере с of_SetKey есть преимущества, но есть и недостатки. Представь, что w_target открываетска из многих скриптов w_source-а - каждый раз писАть набор вызовов of_SetKey, да ещё и в будущем мейнтененс предоставлять? Да и зависит w_target от w_source-а, что не есть хорошо - я бы предпочёл принять аргументы, проверить (если требуется) и рапихать куда надо внутри w_target-а (скажем, в функции, вызываемой фреймворком из события Open).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34543980
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego Anatoly MoskovskyЯ использую следующий подход:
Допустим есть окно w_имя_окна, которому надо передать композитный параметр.
Тогда создаем невизуальный объект n_имя_окна_parm,
в котором объявляются все необходимые именно этому окну параметры.Это то, что называется "стрейфорвард солюшн" - т.е. первое, что приходит в голову. Конечно, можно и этот подход осуществить, если неохота посидеть и подумать как облегчить весь последующий девелопмент, найдя универсальное (дженерик) решение, но с тем-же успехом можно отказаться от наследования и для каждого случая строить отдельный (специальный) объект. Дело в том, что аппликация, над которй я сейчас работаю по контракту, написана именно с помощью этого подхода - ох и приходится мудохаться... Во-первых, все PBLы просто наводнены вот такими классами, цель которых - просто передать параметры. Просто наводнение, фиг найдёшь среди них действительно нужный класс!
Т.е. если я правильно понял из этого абзаца, то единственная проблема состояла в том, что сложно искать нужный класс в библиотеке?
Ну это конечно так, если их именовали как бог на душу положит.

А должен быть единый во всем приложении принцип именования сильносвязанных объектов, такой чтобы 1) видя имя класса параметра, можно опознать в нем этот тип классов, 2) зная имя класса по нему можно определить имя окна, 3) и по имени окна можно определить имя класса параметра.

А насчет первого что приходит в голову, так как раз Ваш способ и пришел мне, как человеку глубоко ленивому, когда-то первым в голову и был отброшен со временем как несопровождаемый в условиях постоянного рефакторинга кода.

ЗЫ. Anatoly Moskovsky==18-я весна
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544000
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlПро передачу параметров в окна.
А зачем вообще открывать окна с параметрами? Намного проще делать так:
Код: plaintext
1.
2.
Open(w_target)
w_target.of_SetKey('somekey', 'value')
w_target.of_SetKey('otherkey', 'othervalue')
Тогда ты сохранишь и читабельность кода и не понадобится заводить структур, и у тебя останется возможность открыть окно с неполным набором параметров. И в будущем, если понадобится добавить в w_target новый параметр, тебе не нужно будет заниматься перекомпиляцией всех объектов которые открывают данное окно (и используют структуру для передачи параметров)

Ага, в особенности с модальными окнами это классная стратегия...
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544008
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlНатуральные ключи всегда лучше.
Готовы поставить крупную сумму на это? :)

А по сути: в промышенном производстве, в т.ч. и ПО, все должно быть унифицировано, даже если в каких-то частных случаях это вредит каким-то качествам продукта. Иначе производство становится дорогим и поэтому неконкурентоспособным. Это себе могут позволить либо производители эксклюзива, где клиент не считает денег, либо мелко-кустарные производители, где качество преобладает над количеством.
Суррогатные ключи - один из элементов унификации, со всеми вытекающими.
Поэтому можно их ненавидеть и всю жизнь применять :)


Про передачу параметров в окна.
А зачем вообще открывать окна с параметрами? Намного проще делать так:
Код: plaintext
1.
2.
Open(w_target)
w_target.of_SetKey('somekey', 'value')
w_target.of_SetKey('otherkey', 'othervalue')

А модальные окна?
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544013
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Филипп
А что Вы думаете по поводу остального?
У Вас среди нас ИМХО наибольший опыт как в разработке так и в руководстве этим.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544031
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18-я весна[quot Ursego][quot Anatoly Moskovsky]Т.е. если я правильно понял из этого абзаца, то единственная проблема состояла в том, что сложно искать нужный класс в библиотеке?
Ну это конечно так, если их именовали как бог на душу положит.Нет, главная проблема - очень много возни в скриптах. Целый экран определений переменных, а затем - длиннейшие CHOOSE CASE-ы с кастингами на все случаи жизни и вызов другой функции, внутри которой - та-же история с CHOOSE CASE-ами и кастингом, но в обратном направлении. И это вместо одного примитивного стринга са всеми нужными параметрами! Павбывав бы! Короче, много лишней девелоперской работы, но мне-то что - оплата почасовая. Готов героически заваливать пиблы всё новыми и новыми объектами, в каждом из которых - лишь несколько инстанс вариэйблз - почему нет, если за дурную работу платят? А с тем-же почтальоном - работа выполнялась бы быстрей, сопровождение сложной аппликации не превращалось бы в длинные попытки понять что в этих f...g скриптах понаписано... Не, это было бы убыточно для меня.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544056
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego White OwlПро создание первичных ключей. Ты перечислил несколько минусов натуральных ключей (все эти минусы можно отмести одним общим возражением - неправильно определено что является натуральным ключом).Приведённое определение - не моё, и звучит очень просто: натуральный ключ - это такой первичный ключ (или кандидат), значения которого кроме уникальной идентификации записей таблицы имеют какой бы то ни было дополнительный смысл в реальной жизни.Я не спорил с определением. Я спорю с теми минусами натурального ключа которые ты перечислил.

UrsegoЗависит от многих обстоятельств. В некоторых ты прав (например, если до черта инсёртов и мало селектов). А кроме этого момента, ЧЕМ ИМЕННО естественные ключи лучше?Ну например тем, что они уже несут какую-то полезную информацию. Разбираясь в ветвистой структуре с кучей связаных таблиц не нужно будет постоянно бегать в главную таблицу и смотреть на какую-же конкретно запись из главной таблицы мы здесь ссылаемся. Во вторых, не нужно вести два индекса в базе. И в главных, используя натуральные ключи я в принципе избавлен от проблем с изобретением и синхронизацией сурогатов.


UrsegoРечь шла вообще о передаче параметров между объектами, окно - просто пример. В твоём примере с of_SetKey есть преимущества, но есть и недостатки. Представь, что w_target открываетска из многих скриптов w_source-а - каждый раз писАть набор вызовов of_SetKey, да ещё и в будущем мейнтененс предоставлять? Да и зависит w_target от w_source-а, что не есть хорошо - я бы предпочёл принять аргументы, проверить (если требуется) и рапихать куда надо внутри w_target-а (скажем, в функции, вызываемой фреймворком из события Open).А ты в любом случае будешь писать набор параметров. Либо присваивая его в структуру, либо вызывая of_SetKey. Более того, при работе со структурой ты всегда передаешь все поля структуры. А если у тебя в создаваемом объекте есть какие-то поля которые редко надо менять? Тогда тебе прийдется в конструкторе объекта проверять поле структуры на некое жесткое значение "use_default_value"...

Да и чисто визуально подход с настройкой объекта после создания объекта легче читается. Вот сравни:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
n_cst_postman	lnv_postman

lnv_postman.of_set_l("order_id", ll_order_id)
lnv_postman.of_set_s("contact_name", ls_contact_name)
lnv_postman.of_set_dt("order_date", ldt_order_date)
lnv_postman.of_set_b("new_record", TRUE)
lnv_postman.of_set_dw("main_datawindow", ldw_main)
lnv_postman.of_set_ds("detail_datastore", ids_detail)

OpenWithParm(w_B, lnv_postman)

//////////////

Open(w_B)

w_B.of_SetKey("order_id", ll_order_id)
w_B.of_SetKey("contact_name", ls_contact_name)
w_B.of_SetKey("order_date", ldt_order_date)
w_B.of_SetKey("new_record", TRUE)
w_B.of_SetKey("main_datawindow", ldw_main)
w_B.of_SetKey("detail_datastore", ids_detail)
я тут сразу буду видеть какой именно объект я настраиваю.
И кстати, PB умеет различать методы на основе типов параметров, не обязательно создавать of_set_l, of_set_s, etc. :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544072
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18-я весна White OwlНатуральные ключи всегда лучше.
Готовы поставить крупную сумму на это? :)Если б был однозначный способ определить что тут лучше что хуже - поставил бы :)

18-я веснаСуррогатные ключи - один из элементов унификации, со всеми вытекающими.
Поэтому можно их ненавидеть и всю жизнь применять :)Да, да, да, десять раз да. Но я их все равно не люблю :)

18-я весна
Про передачу параметров в окна.
А зачем вообще открывать окна с параметрами? Намного проще делать так:
Код: plaintext
1.
2.
Open(w_target)
w_target.of_SetKey('somekey', 'value')
w_target.of_SetKey('otherkey', 'othervalue')

А модальные окна?А что модальные? И модальные точно так же.... ай, мы ж о PowerBuilder говорим! Ну да, с модальными окнами в PB такое не пройдет. Но со всеми остальными окнами и userobject'ами вполне даже прекрасно будет работать.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544079
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18-я весна Филипп
А что Вы думаете по поводу остального?
У Вас среди нас ИМХО наибольший опыт как в разработке так и в руководстве этим.
Там очень буков много, читать лень :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544082
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego 18-я весна[quot Ursego][quot Anatoly Moskovsky]Т.е. если я правильно понял из этого абзаца, то единственная проблема состояла в том, что сложно искать нужный класс в библиотеке?
Ну это конечно так, если их именовали как бог на душу положит.Нет, главная проблема - очень много возни в скриптах. Целый экран определений переменных, а затем - длиннейшие CHOOSE CASE-ы с кастингами на все случаи жизни и вызов другой функции, внутри которой - та-же история с CHOOSE CASE-ами и кастингом, но в обратном направлении. И это вместо одного примитивного стринга са всеми нужными параметрами! Павбывав бы! Короче, много лишней девелоперской работы, но мне-то что - оплата почасовая. Готов героически заваливать пиблы всё новыми и новыми объектами, в каждом из которых - лишь несколько инстанс вариэйблз - почему нет, если за дурную работу платят? А с тем-же почтальоном - работа выполнялась бы быстрей, сопровождение сложной аппликации не превращалось бы в длинные попытки понять что в этих f...g скриптах понаписано... Не, это было бы убыточно для меня.
Все перечисленное возможно как при Вашем подходе так и при моем, так что по-прежнему не вижу обоснования.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544090
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из того, что прочёл, это:
And if there are a lot of elements in l_parm array - <snip>? There are two good ways. The first one is dynamic building of a string which contains the passed data using a separator (the separator might be, for example, the "|" charachter because it is not usually used as data). - ужасно , да и объект почтальон мне тоже не очень...
На мой вкус, самым лучший вариант передачи параметров в РВ - это subclassed message object
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544127
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Филипп, может, решение с конкатенированным стрингом с параметрами внешне выглядит и ужасно, но те 4 с лишним года, что я работал с фреймворком, использующим этот метод, были просто кайфом. Я ведь изпользую ту технологию, что применяется на фирме, где работаю в этот момент, и ничего не решаю. Просто констатирую что мне нравится, а что нет. Может, если когда-нибудь решение как писАть будет зависеть от меня, то за мои любумые методы глаза выцарапаю, а пока покорно "прогибаюсь под изменчивый мир". Из ответов вырисовывается следующая картина: каждый держится хваткой бультерьера за то, с чем свыкся. Наверно, в этом нет ничего плохого, ведь принять что-то новое - всегда шок. Я вот с Оракла на SQL Server спрыгнул - как на Марс попал. Поработал несколько недель -ничего, жить можно! Несмотря на многие годы с PL/SQL вижу, что T-SQL намного удобней в работе - признаю, что моё мнение по этому вопросу было ошибочным (более того, сейчас мне хочется сделать создателям Оракла что-то неприятное за их топорную работу - шоб они в аду в бесконечном курсорном цикле крутились!). Впрочем, это уже вне темы.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544133
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UrsegoИз ответов вырисовывается следующая картина: каждый держится хваткой бультерьера за то, с чем свыкся.
Будете смеятся, начиная с 1999 года, во всех местах, где я работал, делали передачу параметров НЕ так, как мне нравится...
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544142
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UrsegoИз ответов вырисовывается следующая картина: каждый держится хваткой бультерьера за то, с чем свыкся. Наверно, в этом нет ничего плохого, ведь принять что-то новое - всегда шок.
А Вы попробуйте объективно подойти к вопросу, а не "нравится"/"не нравится"/"удобно"/"неудобно".

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

Например для меня приоритетная цель это сопровождаемость кода, поскольку в любую полезную программу приходится вносить изменения.
Одним из критериев сопровождаемости является возможность безболезненного рефакторинга.
Другой критерий - самодокументируемость кода (информативность имен, модульность и пр.) (это актуально, т.к. надо признать, что документация API в общем случае отстает от кода, реализующего этот API).

Приведем еще раз упомянутые техники передачи параметров окну.
1) В ассоциативный массив записываются пары имя=значение, массив передается через OpenWithParm,
2) Для каждого окна объявляется отдельный класс, в инстанс преременных которого объявлены необходимые параметры. Экземпляр такого класса передается также через OpenWithParm.

Теперь рассмотрим в разрезе рефакторинга:
Допустим поменялся набор параметров для вызова окна (добавлен, удален, переименован параметр)
При технике 1 если не везде в вызывающем коде отразить эти изменения, то ошибки после удаления или переименования всплывут только в рантайм при попытке открыть окно.
При технике 2 ошибки после удаления или переименования возникнут уже при компиляции и их придется исправить.

Самодокументирование.
Техника 1. Перечень и тип возможных параметров можно узнать только проанализировав алгоритм разбора этих параметров в окне.
Техника 2. Параметры отделены от алгоритма и четко видны.

Так для меня очевидно, что при заявленной мною цели техника 2 более пригодна чем техника 1.

Удобство я тоже конечно принимаю во внимание, но далеко не в первую очередь, потому что пока работаешь один удобство может и выходит на первый план, но когда над проектом работает несколько человек, то у каждого возникает свое удобство. И если начальник (тот кто принимает решение как делать) не понимает, что то что ему удобно в итоге может привести к трудно находимым багам, то возникают проблемы, которые ложатся на подчиненных.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544432
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Филипп
На мой вкус, самым лучший вариант передачи параметров в РВ - это subclassed message object
Согласен. На мой взгляд этот метод больше всего соответствует идеологии ООП.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544633
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spas2001 ФилиппНа мой вкус, самым лучший вариант передачи параметров в РВ - это subclassed message objectСогласен. На мой взгляд этот метод больше всего соответствует идеологии ООП.
А можно пример вызова с передачей например двух аргументов? (Чтобы не гадать, что имеется в виду и потом не спорить с собственными домыслами :) )
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544761
Ursego
Даже в тех субэдэшках, что имеют внутренние средства генерации ключей, лучше ими не пользоваться (и в большинстве проектов, куда меня засылала партия, они и не использовались). Решение простое: имеется таблица, состоящая из двух полей: entity_name и next_value. Создал в системе новую сущность - загоняешь в таблицу запись для неё:

Код: plaintext
INSERT INTO tbl_ids (entity_name, next_value) VALUES ('emp_id',  1 );


Расскажите это тем, кто использует интенсивные вставки в многопользовательских приложениях.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34544989
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Михаил ПанайотРасскажите это тем, кто использует интенсивные вставки в многопользовательских приложениях.
Зря Вы так :)
Я намеренно не комментировал раздел, связанный с работой с БД, потому что если уж устраивать флейм, то хотя бы по PowerBuilderу.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34545917
Фотография Шатёркин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да ладно - sql тоже затронем :)

автор
*** BAD code: ***

SELECT @country_name = country.country_name
FROM country,
city,
address
WHERE country.country_id = city.country_id
AND city.city_id = address.city_id
AND address.address_id = @address_id;

*** GOOD code: ***
SELECT @country_name = country.country_name
FROM country
JOIN city
ON city.country_id = country.country_id
JOIN address
ON address.city_id = city.city_id
AND address.address_id = @address_id;

что-то мне подсказывает, что всё с точностью до наоборот :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34545938
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шатёркинчто-то мне подсказывает, что всё с точностью до наоборот :)
Вообще, хотя запросы и эквивалентны, второй вариант, как показывает практика, может оказаться более понятным для оптимизатора (с соотв. более "хорошим" планом).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34545957
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шатёркинда ладно - sql тоже затронем :)

автор
*** BAD code: ***

SELECT @country_name = country.country_name
FROM country,
city,
address
WHERE country.country_id = city.country_id
AND city.city_id = address.city_id
AND address.address_id = @address_id;

*** GOOD code: ***
SELECT @country_name = country.country_name
FROM country
JOIN city
ON city.country_id = country.country_id
JOIN address
ON address.city_id = city.city_id
AND address.address_id = @address_id;

что-то мне подсказывает, что всё с точностью до наоборот :)

Неверно подсказывает :)
На самом деле должно быть: joins - отдельно, where - отдельно, а не все в кучу как в обоих примерах.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34545981
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шатёркинчто-то мне подсказывает, что всё с точностью до наоборот :) что характерно в MSSQL2005 теперь OUTER JOIN можно написать только вторым способом. *= больше не катит.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546228
Фотография Шатёркин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во гады :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546250
Фотография Шатёркин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так скажите - почему плохо связывать таблицы в WHERE, ну кроме облегчения жизни оптимизатору
не дайте умереть идиотом :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546361
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот из BOL2000 про *= и *=
BOL2000In earlier versions of Microsoft® SQL Server™ 2000, left and right outer join conditions were specified in the WHERE clause using the *= and =* operators. In some cases, this syntax results in an ambiguous query that can be interpreted in more than one way. SQL-92 compliant outer joins are specified in the FROM clause and do not result in this ambiguity. Because the SQL-92 syntax is more precise, detailed information about using the old Transact-SQL outer join syntax in the WHERE clause is not included with this release. The syntax may not be supported in a future version of SQL Server. Any statements using the Transact-SQL outer joins should be changed to use the SQL-92 syntax.

The SQL-92 standard does support the specification of inner joins in either the FROM or WHERE clause. Inner joins specified in the WHERE clause do not have the same problems with ambiguity as the Transact-SQL outer join syntax.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546586
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шатёркинтак скажите - почему плохо связывать таблицы в WHERE, ну кроме облегчения жизни оптимизатору
не дайте умереть идиотом :)
Исключительно исходя из того, что потом кто-то будет разбираться с этим кодом и модифицировать его.
Поэтому лучше позаботиться об этом человеке и сразу разделить служебную часть запроса (соединения) от прикладной (фильтр).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546784
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шатёркинда ладно - sql тоже затронем :)

автор
*** BAD code: ***

SELECT @country_name = country.country_name
FROM country,
city,
address
WHERE country.country_id = city.country_id
AND city.city_id = address.city_id
AND address.address_id = @address_id;

*** GOOD code: ***
SELECT @country_name = country.country_name
FROM country
JOIN city
ON city.country_id = country.country_id
JOIN address
ON address.city_id = city.city_id
AND address.address_id = @address_id;

что-то мне подсказывает, что всё с точностью до наоборот :)Я до недавнего времени тоже не был поклонником метода с ключевым словом JOIN - более того, стоял на "старом" синтаксисе насмерть, как 26 бакинских комиссаров. А всё из-за многолоетней привычки. Но на новой работе меня заставили перейти на новый синтакс, и поработав с ним я стал его поклонником (думаю, отзывы в этой ветке тоже кое-что да изменят в моих взглядах). Если вкратце, то при WHERE-методе всё свалено в одну кучу; при JOIN-методе мы имеем несколько меньших "кучек", и каждый раз можем комфортно сосредоточиться на том, как одна таблица связана с общей картиной; проанализировав её, переходим к следующей. Как в притче с веником: целый веник сломать трудно, а по прутику - легко!
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546829
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18-я веснарассмотрим в разрезе рефакторинга:
Допустим поменялся набор параметров для вызова окна (добавлен, удален, переименован параметр)
При технике 1 если не везде в вызывающем коде отразить эти изменения, то ошибки после удаления или переименования всплывут только в рантайм при попытке открыть окно.
При технике 2 ошибки после удаления или переименования возникнут уже при компиляции и их придется исправить.ОК, ошибки всплывут на несколько минут позже, при юнит-тесте. Видишь, что параметр не получен - смотришь почему (в вызывающем скрипте). Из-за этого наводнять аппликацию десятками объектов, да ещё и поддерживать (каждый раз изменять) их?

18-я веснаСамодокументирование.
Техника 1. Перечень и тип возможных параметров можно узнать только проанализировав алгоритм разбора этих параметров в окне.
Техника 2. Параметры отделены от алгоритма и четко видны.При первом методе всё сосредоточено в скрипте, принимающем параметры (Open, pfc_open, uf_get_key() или что бы там ни было) - имею в виду в плане самодокументации, чтоб понять что передаётся. Т.е. всё - в одном месте, а не разбросано по разным частям аппликации как в методе 2. О чём ещё мечтать бедному программисту? Кроме того, не все параметры всегда передаются (имеются объекты параметров, используемые в разных обстоятельствах - иначе пришлось бы иметь не сотни, а тысячи подобных "красавцев"). И вот я смотрю на поля объекта параметров, которые, как ты пишешь, "четко видны", и вижу, что имеются незаполненные. Что это? Баг или нет? Как определить? Всё равно придётся лезть в открывающий скрипт и смотреть логику, алгоритм, а при неполучении ожидаемого результата - дебагировать.

Конечно, в твоих контраргументах есть много рационального, хоть я на них и ответил своими. Но тут мы имеем то, что всегда имеем - палку о двух концах, а именно: какой метод ни возьми, он имеет достоинства и недостатки. Единственный выход - ждать пенсии.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546911
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursegoтысячи подобных "красавцев"
Честно говоря у меня есть серьезные сомнения в том, а было ли вообще хоть какое-либо проектирование, если в приложении возникли тысячи классов окон. Тут скорее похоже на copy-paste.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34546918
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18-я весна Ursegoтысячи подобных "красавцев"
Честно говоря у меня есть серьезные сомнения в том, а было ли вообще хоть какое-либо проектирование, если в приложении возникли тысячи классов окон. Тут скорее похоже на copy-paste.Как говаривал один мой знакомый: "Зачем нужно модульное программирование, если есть блочное копирование?"
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34547224
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky spas2001 ФилиппНа мой вкус, самым лучший вариант передачи параметров в РВ - это subclassed message objectСогласен. На мой взгляд этот метод больше всего соответствует идеологии ООП.
А можно пример вызова с передачей например двух аргументов? (Чтобы не гадать, что имеется в виду и потом не спорить с собственными домыслами :) )
Это вы о чём? Об открывании окон? :-))))))))))))))))))
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34547886
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ФилиппЭто вы о чём? Об открывании окон? :-))))))))))))))))))
Неа, мы о том как коптить сало.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34548085
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Anatoly
А что, PowerObjectParm уже не существует
У меня чаще всего реализован в приложениях какой-нибудь message handler, который собственно и занимается исключительно обработкой сообщений, немножко муторно было делать в самом начале, зато нормально использовать

ЗЫ: Никого не хотел обидеть, у каждого свои принципы и методы (а также доводы)
Либо человек пишет красиво, либо нет (есть писатели, а есть графоманы)

А думать за оптимизатор не надо, его надо настраивать

------------------------------------------------------
Главная деталь любой машины - голова ее владельца
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34548192
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spas2001А думать за оптимизатор не надо, его надо настраивать
Ой, не смешите мои тапочки... Сколько там будет вариантов соединений когда у Вас в запросе полсотни таблиц? И что Вы в оптимизаторе крутить-то будете по этому поводу? Очень интересно услышать.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34548285
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spas2001To Anatoly
А что, PowerObjectParm уже не существует
Я про него весь этот топик говорю.

А мой вопрос был: как конкретно реализована передача разных наборов аргументов в разные окна используя наследование Message?
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34548314
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк spas2001А думать за оптимизатор не надо, его надо настраивать
Ой, не смешите мои тапочки... Сколько там будет вариантов соединений когда у Вас в запросе полсотни таблиц? И что Вы в оптимизаторе крутить-то будете по этому поводу? Очень интересно услышать.
В этом случае надо оптимизировать программиста :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550012
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА мой вопрос был: как конкретно реализована передача разных наборов аргументов в разные окна используя наследование Message?Я так предполагаю, имеется некий класс (унаследованный от Message) с полями для передачи самых часто встречающихся в приложении сущностей (а в каждой аппликации их как правило хоть несколько штук да имеется) плюс, быть может, поинтеры для транспортировки datawindows, datastores и NVOs и прочих непримитивных типов, а от него унаследованы другие, в которых объявлены дополнительные, уже специфические для тех частей аппликации где объекты будут использованы. Причём базовый класс может быть инстантиирован для использования as is если имеющихся в нём полей достаточно. Или не угадал?
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550015
18-я весна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego Anatoly MoskovskyА мой вопрос был: как конкретно реализована передача разных наборов аргументов в разные окна используя наследование Message?Я так предполагаю, имеется некий класс (унаследованный от Message) с полями для передачи самых часто встречающихся в приложении сущностей (а в каждой аппликации их как правило хоть несколько штук да имеется) плюс, быть может, поинтеры для транспортировки datawindows, datastores и NVOs и прочих непримитивных типов, а от него унаследованы другие, в которых объявлены дополнительные, уже специфические для тех частей аппликации где объекты будут использованы. Причём базовый класс может быть инстантиирован для использования as is если имеющихся в нём полей достаточно. Или не угадал?
Гадать можно долго, у меня самого есть версии. Пусть те, кто упомянул, сами уточнят.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550030
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык давай версии - может, что-нибуть гениальное придумаем.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550391
Фотография urvas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист!
Пиши так, чтобы конечному пользователю было комфортно, удобно и приятно.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550805
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky Локшин Марк spas2001А думать за оптимизатор не надо, его надо настраивать
Ой, не смешите мои тапочки... Сколько там будет вариантов соединений когда у Вас в запросе полсотни таблиц? И что Вы в оптимизаторе крутить-то будете по этому поводу? Очень интересно услышать.
В этом случае надо оптимизировать программиста :)

Верно сказано, спорить грех
Приходится и так делать, особенно на новом месте работы
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550902
ZhV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из своего... может кому будет полезно

Для вызова окон в качестве параметра использутеся структура, которая создана один раз и больше никогда не менялась - не было нужды
Код: plaintext
1.
2.
3.
global type s_param_call from structure
string         	s_param[]
powerobject	po_ref[]
end type

Обратите внимание на po_ref[] - это может быть массив ЛЮБЫХ обьектов powerbuilder-а.
Но на "принимающей" стороне нужно обязательно контролировать размер массива и TypeOf обьектов

s_param[] - для некоторых классов устанавливаются специальные соглашение.
Вот код снятия параметра и соотвтесвующий комментарий в event Open() в общем ancestor-е одного из классов

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
/****** Параметры вызова
s_param_call ist_call

s_param[]
1 - имя поля  id
2 - значение ID - строчное или String(Long)
3 - сообщение для title
4 - dataobject для dw_master - если в inherited window не задан  опционально
5 - номер строки в этом datawindow
6 - произвольная строка параметров  c разделителем ,    например 
     noborder   - убрать border
    exitescape - выход по Escape
     noobject   - пустой или недоступный обьект - ссылки на внешний datawindow  не использовать

po_ref[1] - datawindow , по отношению к которому делается редактирование или ввод
****/

IF Not(IsValid(Message.powerobjectparm)) THEN 
	is_error = 'Call parms not passed'   
ELSE
   ls_s = Classname(Message.powerobjectparm)
   IF ls_s = "s_param_call" THEN 
	ist_call = Message.powerobjectparm
   ELSE
            is_error = 'Invalid  parms object'
   END IF
END IF
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34550930
ZhV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще одна фишка - предопределенные (стандартные) event-ы не должны содержать длинный функционально-содержательный код.
Например если по Clicked() запускается сложная обработка, то код обработки описывается в отдельной специальной
функции или event-е с "говорящим" названием, а в самом Clicked() - только вызов этого модуля
Лично я как-то сильно попотел, когда долго искал "работающий" код - и нашел пару сотен строк , которые висели
на редко пользуемом event-е - itemfocuschange

Причем часто удобно это делать в режиме асинхронного вызова по символьному имени и с передачей параметров через Message,
например
PostEvent.('ue_do_special_work',0,ls_parm)

Если в конкретном окне/обьекте такой event отсутствует - то runtime ошибки не будет - это удобно для обобщенных вызовов.

К сожалению, так можно передать только строчный параметр, но можно условиться о способе упаковки в этот строчный
параметр для Message
Например , вот есть событие
Код: plaintext
1.
2.
3.
4.
5.
//event ue_do_special_work(long al_id)
IF IsNull(al_id) THEN 
    al_id = Long(String(Message.LongParm, "address"))  // прошел асинхронный вызов -  взять al_id из Message
END IF
...
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34552426
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
urvasПрограммист!
Пиши так, чтобы конечному пользователю было комфортно, удобно и приятно.Это уже абсолютно другая тема, хоть и важная. А сейчас обсуждается тема - чтоб было комфортно, удобно и приятно программисту. Мы ж тоже люди!
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34552781
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego urvasПрограммист!
Пиши так, чтобы конечному пользователю было комфортно, удобно и приятно.Это уже абсолютно другая тема, хоть и важная. А сейчас обсуждается тема - чтоб было комфортно, удобно и приятно программисту. Мы ж тоже люди!"Программисты тоже люди"... Хм... какая странная концепция.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34858737
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Статья о стиле программирования переработана и дополнена, если кому интересно.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34859121
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про то, что иметь много точек выхода из функции не есть хорошая практика, Вам кажется уже говорили... Но вот это
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
 SELECT @country_name = country.country_name
   FROM country,
	 city,
	 address
  WHERE country.country_id = city.country_id
    AND city.city_id = address.city_id
    AND address.address_id = @address_id;

*** GOOD code (the "divide and conquer" approach): *** 



 SELECT @country_name = country_name
   FROM country
  WHERE country_id =

	(SELECT country_id
	   FROM city
	  WHERE city_id =

		(SELECT	 city_id
		   FROM address
		  WHERE address_id = @address_id))
Таким кодом оптимизатор запутать на раз можно. Его не удобно модифицировать. Если вдруг потребуется оптимизатору указать hint, то при таком способе записи это будет сделать невозможно.
Я бы написал например так:
Код: plaintext
1.
2.
3.
SELECT @country_name = country.country_name
   FROM country join city on country.country_id = city.country_id
	          join address on city.city_id = address.city_id
  WHERE address.address_id = @address_id;
PS. Статью не читал - просто это первое, что бросилось в глаза.
PSS. А еще у Вас шрифт в статье дурацкий - читать сложно. :)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34859148
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И то что дальше объявляется very good code - тоже под большим вопросом.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34859964
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Маркиметь много точек выхода из функции не есть хорошая практика
В статье четко написано в каких именно случаях правильнее отойти от правила единой точки выхода.
И в этой части я с автором согласен. Так как иначе возникают чрезмерные вложенности if в которых часто забывают else и которые трудно модифицировать и отлаживать, и в которых часто дублируется код из разных уровней вложенности. Также возникают всевозможные флаги которые по сути те же выходы, но формально (синтаксически) ими не являются и это затрудняет понимание того, что делает код.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34860522
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВ статье четко написано в каких именно случаях правильнее отойти от правила единой точки выхода.
Да, есть, при беглом просмотре не заметил. Но все равно специально писать условия через not - менее наглядно. Потому как обычно условия формулируются по принципу "если то-то, то так-то", а не "если не то-то то так-то". Соответственно код не перегруженный кучей условий not более понятен для восприятия.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34861527
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Марк, ты же знаешь - сколько программистов, столько и мнений :-). Я описал своё видение, и если другие считают наоборот - это вполне нормально и ожидаемо. Описанные трюки и решения не из пальца высосаны, а либо взяты от мастеров, с которыми общался, либо пришёл к ним методом проб и ошибок сожрав не одну собаку. Заранее знаю, что у статьи будет немало оппонентов, причём зачастую привыкших к не совсем правильным решениям, приняв их в начале как авторитетные (я могу сейчас в пух и прах разбомбить ту-же теорию о единой точке выхода, с которой многие носятся как с писанной торбой, хотя легче отослать к патриарху - Дейкстре), а когда привык к чему-нибудь, то отвыкнуть очень нелегко (примеры - курение или сваливание нескольких SQLей в одну кучу). Я всё это не от нефиг делать написАл, а потому что наболело - работал я тогда в фирме (слава Богу, свалил, не поддавшись на предложение остаться на постоянку в правительстве провинции - такого счастья мне не надо!), где в функциях было больше строк кода, чем в исходние первой версии Линукса (имею в виду В ОДНОЙ ФУНКЦИИ!!!), а мой экран был залапан пальцем так, что периодически приходилось вытирать отпечатки как после ограбления (например, держал на экране уровень 5-го таба из 7, пытаясь найти if-овский end if с помощью скроллинга вниз).

Кстати, всем привет от живущего у нас в Калгари мужичка, бывшего частью PowerBuilder team. Увы, работает дибиэем в нефтяной отрасли, в будущее PowerBuilder-а не верит... Кстати, однофамилец того самого великого Дейкстры!
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34861568
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyТакже возникают всевозможные флаги которые по сути те же выходы, но формально (синтаксически) ими не являются и это затрудняет понимание того, что делает код.Абсолютно верно! Какая логически разница сделать return сразу или через посредника, сначала перейдя к нему, чему хошь-не хошь будет посвящено несколько лишних строк? Это как exception handler - абсолютно тот-же самый goto если говорить в рамках одного скрипта. Но скажи, что используешь goto - забросают камнями. А какая нафиг разница? Не использовать этот удобный в определённых условиях оператор только потому, что несколько десятилетий назад с ним боролись, пытаясь заменить на if (программеры старой закалки продолжали писать на появившихся языках 3-го поколения в стиле ассемблера, к которому привыкли, производя спагетти-код - тогда борьба с goto была оправдана, но вошла во все учебники программирования явно потому, что авторы бездумно повторяли чужую и устаревшую мысль). Короче, думать надо, а не делать copy/paste чужих идей на полном автомате.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34861578
asmod64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМНО Неплохая статья и в нагрузку еще
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862445
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego Я всё это не от нефиг делать написАл, а потому что наболело - работал я тогда в фирме
Это понятно, что плохое правило лучше чем никакое. Но не нужно же давать откровенно вредные советы. Про good code - я уже упомянул. Посмотрим на very good code. Я уж не говорю про то, что разобраться в 4 строках кода легче чем в 9 + объявление переменных и то что в последствии между этими строками кода еще чего-нибудь может получиться. Я не говорю, что таким способом записи фактически жестко прописывается план исполнения... Понимаете, 3 select'а написанные подряд - это совсем не тоже самое, что 1 select. В результате далеко не всегда будет одно и тоже.
UrsegoКакая логически разница сделать return сразу или через посредника, сначала перейдя к нему, чему хошь-не хошь будет посвящено несколько лишних строк?
Разница вот какая. Если у меня есть один return, то я точно знаю место в скрипте, которое будет исполняться непосредственно перед выходом из процедуры. Соответственно если мне понадобилось изменить процедуру так, чтобы для каких-то целей выделялся какой-то ресурс, то код по его освобождению я напишу 1 раз в конце функции. Если у меня много точек выхода, то я должен найти все и заменить
Код: plaintext
1.
2.
3.
4.
5.
if not condition then return - 1 
на 
if not condition then
  Free(X)
  return - 1 
end if
Так что польза от 1 точки выхода есть.
Кстати по поводу оформления таких кусочков кода
Я предпочитаю всегда писать
Код: plaintext
1.
2.
if @a =  1  begin
  select  1 
end
а не
Код: plaintext
1.
if @a =  1  
  select  1 
Почему? 1. операторные скобки (да и обычные) полезно набирать "на автомате", а потом уже внутри писать текст - тогда потом не нужно будет нудно считать где забыл открыть/закрыть. 2. - когда понадобится внести второй оператор не нужно будет искать конец оператора который после if (а select может быть и на страницу и на две). 3. Можно просто напросто забыть дописать скобки - естественно получится не то, что нужно.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862547
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркСоответственно если мне понадобилось изменить процедуру так, чтобы для каких-то целей выделялся какой-то ресурс, то код по его освобождению я напишу 1 раз в конце функции. Если у меня много точек выхода, то я должен найти все и заменить

Кошмар! "найти и заменить"... нет слов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
try
    ...
    if not condition throw conditionException
    ...
    returnValue = SUCCESS
catch (conditionException)
    ...
    returnValue = FAILURE
finally
    Free(X)
    return returnValue
end try
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862597
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗоринАндрейКошмар! "найти и заменить"... нет слов.
1. Сколько точек выхода будет в данной функции? Посчитать по пальцам?
2. Оператор try есть не во всех версиях PB (по-моему с 7).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862798
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркЕсли у меня есть один return, то я точно знаю место в скрипте, которое будет исполняться непосредственно перед выходом из процедуры. Соответственно если мне понадобилось изменить процедуру так, чтобы для каких-то целей выделялся какой-то ресурс, то код по его освобождению я напишу 1 раз в конце функции. Если у меня много точек выхода, то я должен найти все и заменить
Код: plaintext
1.
2.
3.
4.
5.
if not condition then return - 1 
на 
if not condition then
  Free(X)
  return - 1 
end if
Так что польза от 1 точки выхода есть.

Еще раз.
"if not condition then return -1" касается только предусловий, т.е. определения возможности выполнения основного кода ф-и. И в этот момент о выделении или освобождении ресурсов речь еще не идет.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862818
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк1. Сколько точек выхода будет в данной функции? Посчитать по пальцам?
Одна.
Локшин Марк2. Оператор try есть не во всех версиях PB (по-моему с 7).
Если кто-то еще пользуется шестеркой - мне остается только посочувствовать.
ИМХО странно вырабатывать стиль принимая во внимание версии 10летней давности.
Все равно что сказать - мы не будем использовать ANSI Join syntax потому что его не было в версии x.x восемь лет назад.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862827
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЕще раз.
"if not condition then return -1" касается только предусловий, т.е. определения возможности выполнения основного кода ф-и. И в этот момент о выделении или освобождении ресурсов речь еще не идет.
В случае нескольких уровней Exception позволяет выйти сразу на верхний уровень не засоряя код чем-то таким
Код: plaintext
1.
2.
rc = of_function(...)
if rc = FAILURE return FAILURE
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862841
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyкасается только предусловий, т.е. определения возможности выполнения основного кода ф-и. И в этот момент о выделении или освобождении ресурсов речь еще не идет.
Никто не сказал, что "parameters checking" не потянет необходимости выделения ресурсов. Например - передаются 2 параметра - имена файлов, а в функции необходимо чтобы файлы уже существовали. Поэтому мне нужно будет попытаться открыть - 1 файл и завершиться с ошибкой если его нет, а затем открыть второй файл и освободить первый файл и завершиться с ошибкой если нет второго. И это всего лишь "parameters checking".
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862945
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗоринАндрейОдна.
Ну и к чему тогда твой пассаж?
Я понимаю, если бы это было ответом на это
Anatoly MoskovskyТак как иначе возникают чрезмерные вложенности if в которых часто забывают else и которые трудно модифицировать и отлаживать,
или вот это
UrsegoНо скажи, что используешь goto - забросают камнями. А какая нафиг разница? Не использовать этот удобный в определённых условиях оператор
Но оспаривать кодом с одной точкой возврата мой тезис
Локшин Маркиметь много точек выхода из функции не есть хорошая практика
и далее поясняющий пример по-моему как-то не логично.
ЗоринАндрейЕсли кто-то еще пользуется шестеркой - мне остается только посочувствовать.
Это было так, к слову :). Но ведь кто-то еще пользуется.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34862996
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код программиста - это тот же почерк
Чаще всего он уникален, есть просто вещи которыми каждый руководствуется неосознано (речь идет не о новичках, которым как первоклашкам и надо выработать почерк - косые палочки писать:)). Стиль вырабатывается годами
Так что религиозные войны тут не к чему, лучше сообща сформировать правила и их альтернативы
-----------------------------------------------------------------------------
Главная деталь любой машины - голова ее владельца
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863032
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркНу и к чему тогда твой пассаж?Э.... Ну да... Я тут про годовщину свадьбы забыл.
Не то что форум читать внимательно...
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863294
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк Anatoly Moskovskyкасается только предусловий, т.е. определения возможности выполнения основного кода ф-и. И в этот момент о выделении или освобождении ресурсов речь еще не идет.
Никто не сказал, что "parameters checking" не потянет необходимости выделения ресурсов. Например - передаются 2 параметра - имена файлов, а в функции необходимо чтобы файлы уже существовали. Поэтому мне нужно будет попытаться открыть - 1 файл и завершиться с ошибкой если его нет, а затем открыть второй файл и освободить первый файл и завершиться с ошибкой если нет второго. И это всего лишь "parameters checking".
Этот случай не предусловие. Ошибка происходит уже при работе основного кода функции (в котором попытка открытия файла для последующего чтения используется для проверки наличия файла).
В этом случае правильнее всего применять генерацию исключения при ошибке чтения файла с освобождением ресурсов в FINALLY. А проверку наличия выделить в отдельный блок кода в начале ф-и, не мешая его с обработкой файла.

Я уже не говорю о том, что должна быть отдельная ф-я проверяющая наличие файла (допустим что в PB такой нет) , и тогда никаких проблем в освобождением ресурсов не будет. И читаемость кода повышается - явный вызов of_CheckIfFileExists понятен сразу, тогда как FileOpen; If ... еще нужно интерпретировать из контекста.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863334
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, goto - это жесть
-----------------------------------------------------------------------------
Главная деталь любой машины - голова ее владельца
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863378
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА проверку наличия выделить в отдельный блок кода в начале ф-и, не мешая его с обработкой файла.

Я уже не говорю о том, что должна быть отдельная ф-я проверяющая наличие файла (допустим что в PB такой нет) , и тогда никаких проблем в освобождением ресурсов не будет. И читаемость кода повышается - явный вызов of_CheckIfFileExists понятен сразу, тогда как FileOpen; If ... еще нужно интерпретировать из контекста.
Ага щаз. А если голову включить? Проверка должна, именно должна захватывать файл чтобы никто с ним ничего не мог сделать. FileExists то проверить наличие сможет, но только для Вашего личного успокоения, и ничего более. Потому как сразу после исполнения FileExists он может быть кем угодно удален (сюрприз-сюрприз). И хоть обпишитесь вы своих функций проверки - все будет бестолку. Я же говорю - не нужно давать откровенно вредных советов.
Вы Анатолий (если сами не заметили) только что просто очень наглядно продемонстрировали к чему такой подход ведет.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863458
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркАга щаз. А если голову включить? Проверка должна, именно должна захватывать файл чтобы никто с ним ничего не мог сделать. FileExists то проверить наличие сможет, но только для Вашего личного успокоения, и ничего более. Потому как сразу после исполнения FileExists он может быть кем угодно удален (сюрприз-сюрприз).
Вы невнимательно читаете. У меня проверка наличия вынесена отдельно, но при этом обработка ошибок при чтении файлов сохраняется. Эти два действия не одно и тоже и мешать их в кучу - только затруднять дальнейшее понимание написанного кода.
Отсутствие файла при проверке предусловий - штатная ситуация, а вот исчезновение файла после проверки на наличие - это нештатная ситуация (исключение) и решаются они разными способами.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863678
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyОтсутствие файла при проверке предусловий - штатная ситуация, а вот исчезновение файла после проверки на наличие - это нештатная ситуация (исключение) и решаются они разными способами.
Что значит разными способами? Какая мне разница когда удалили файл - за секунду до того как я его открыл или за час? С чего это вдруг в одном случае не штатная ситуация, а в другом - штатная? И почему от этого должен зависить способ решиния проблемы?
Anatoly Moskovskyобработка ошибок при чтении файлов сохраняется
По-моему про это вообще никто не говорил. Также никто не говорил, например, о проблемах с взаимоблокировками.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863760
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк Anatoly MoskovskyОтсутствие файла при проверке предусловий - штатная ситуация, а вот исчезновение файла после проверки на наличие - это нештатная ситуация (исключение) и решаются они разными способами.
Что значит разными способами? Какая мне разница когда удалили файл - за секунду до того как я его открыл или за час? С чего это вдруг в одном случае не штатная ситуация, а в другом - штатная? И почему от этого должен зависить способ решиния проблемы?
Anatoly Moskovskyобработка ошибок при чтении файлов сохраняется
По-моему про это вообще никто не говорил. Также никто не говорил, например, о проблемах с взаимоблокировками.
Все описанные Вами проблемы могут возникнуть независимо от стиля кодирования, поэтому не вижу смысла обсуждать их в этом топике.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863841
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВсе описанные Вами проблемы могут возникнуть независимо от стиля кодирования, поэтому не вижу смысла обсуждать их в этом топике.
Проблемы -то возникнуть могут только как Вы их предлагаете решать? В таком духе:
Код: plaintext
1.
2.
3.
c =  2 
b =  2 
if c <>  2  then return - 1 
if b <>  2  then return - 1 
Понимаете, если есть задача использовать ресурс, то проверять его наличие не захватив его - бесполезно. Есть, конечно, небольшие оговорки, но в общем и целом - картина такая. Зачем два раза проверять? Чтобы сохранить чистоту идеи? Почему тогда 3 раза не проверить?
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34863902
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк Anatoly MoskovskyВсе описанные Вами проблемы могут возникнуть независимо от стиля кодирования, поэтому не вижу смысла обсуждать их в этом топике.
Проблемы -то возникнуть могут только как Вы их предлагаете решать?
Есть множество способов решить указанные проблемы, но ни один не имеет отношение к стилю кодирования (напомню тему топика). По этой причине я не собираюсь их обсуждать. Кроме того это просто неинтересно - все техники работы с разделяемыми ресурсами давно известны и тут нечего обсуждать.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34864005
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЕсть множество способов решить указанные проблемы, но ни один не имеет отношение к стилю кодирования (напомню тему топика). По этой причине я не собираюсь их обсуждать. Кроме того это просто неинтересно - все техники работы с разделяемыми ресурсами давно известны и тут нечего обсуждать.
Вообще-то я просто считаю, что Вы сами привели пример, когда Ваш стиль либо заставляет писать абсолютно лишний код, либо провоцирует на ошибку при решении конкретной задачи. И все это навязанно именно стилем. В обратном Вы меня не убедили.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34866221
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Марк, в твоих рассуждениях мне видится вот какой недостаток - ты берёшь какие-то редкие (чтоб не сказать крайние) случаи, в которых таки да мой подход хуже, и проецируешь его на общие случаи. Например, если в скрипте требуется освобождать ресурсы, то, естественно, глупо копировать один и то-же фрагмент 20 раз - лучше сделать одну точку выхода, перед которой и освободить эти ресурсы (я ведь не написал, что набъю морду любому, кто использует единую точку выхода). Или другая ситуация (пример с ресурсами не очень характерен для ПБ, разве только если надо сделать несколько DESTROY-ев) - многочисленные места в скрипте, которые могут закончиться неуспешно - конечно, можно испльзовать икепшн хендлер или даже столь ненавистное "иди на..." (GOTO), но я бы сделал иначе: каждый раз, когда произошёл сбой, возвращать код сообщения об ошибке во внешнюю функцию, которая будет иметь следуюющий код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
string ls_err_msg_code

ls_err_msg_code = this.uf_blah_blah_blah()
if ls_err_msg_code <> '' then
   {write to error log}
   {display error message}
   return FAILURE
end if

return SUCCESS

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

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

Кстати, спасибо Анаталию Московскому - отвечаешь за меня фактически так, как ответил бы я!
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34866278
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UrsegoТаким образом будет достигнуто ещё одно преимущество - зёрна отделены от плевел, интересная бизнес-логика отделена от технического кода обработки ошибки
Ну а где те же тот же DESTROY писать? И write to error log лучше делать внутри функции. Лучше всегда делать как говорят в армии - безобразно, но однообразно, в конечном итоге это дает результат.
UrsegoДа, такое может быть, и бывает, особенно если структуру базы данных ваял какой-нибудь... эээ... нехороший человек. И в таких особых случаях действительно надо думать как сделать лучше - мой вариант вполне может не подойти. Но чаще всего (из моего опыта) оба варианта идентичны.Из моего опыта - даже на запросах чуть сложней приведенного уже могут быть проблемы (На том же MS SQL).
А уж когда какой-нибудь отчет напишут так раз в 5-6 завернув select'ы у меня обычно слов кроме матерных не бывает. Типа б$%*ь, какого х%$ агрегация 1000 строчек на 4-х процессорном серваке идет 10 секунд.
И сиди переписывай такие творения. Но зато потом почему-то начинает летать.
А уж то, что объявлено very good code на самом деле вообще wrong code само по себе.
Ursegoа писАл я для особо ударённых, чей код приходилось разгребать (ну, и совсем новичкам это должно быть тоже полезно)Ну так поэтому и надо тогда особенно тщательно подходить к такому вопросу.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34866437
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркНу а где те же тот же DESTROY писать?В аппликации, над которой я сейчас работаю, вообще нет DESTROY-ев. Я сначала не врубился, говорю шефу - дык мемеори лик, блин, будет! А он ржёт - зачем, говорит, лишнее писАть, если гарбич коллектор запускается периодически? Блин, прям Джава какая-то...

Локшин МаркИ write to error log лучше делать внутри функции. Лучше всегда делать как говорят в армии - безобразно , но однообразноЭта фраза всё ставит на свои места - наши мнения диаметрально противоположны. Можешь писАть безобразно, если хочешь - всё равно я с твоей аппликацией не буду работать. :-)

Локшин Маркв конечном итоге это дает результат.Напиши вообще всю аппликацию в виде одной функции. Конечно, придётся изрядно помучиться и даже проклясть всё на свете, но в конечном итоге это даст результат.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34866439
Фотография Филипп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UrsegoВ аппликации, над которой я сейчас работаю, вообще нет DESTROY-ев. Я сначала не врубился, говорю шефу - дык мемеори лик, блин, будет! А он ржёт - зачем, говорит, лишнее писАть, если гарбич коллектор запускается периодически? Блин, прям Джава какая-то...
Так ты ему поясни что он козёл отмороженный...
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #34866752
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ursego Локшин МаркИ write to error log лучше делать внутри функции. Лучше всегда делать как говорят в армии - безобразно , но однообразноЭта фраза всё ставит на свои места - наши мнения диаметрально противоположны.
Смысл фразы не в том, что безобразно, а в том, что однообразно . Например однообразный интерфейс он может быть скучен, может быть как-то иначе можно было бы сделать чтобы как-то быстрее работать, но человеку будут более-менее понятны все принципы работы с формами, если он изучит работу с одной. И со стилем оформления точно также. Конечно, исключения допустимы, но они лишь, как известно, подтверждают правила.
UrsegoМожешь писАть безобразно, если хочешь - всё равно я с твоей аппликацией не буду работать
А это как жизнь еще повернется :)
Ursegoно в конечном итоге это даст результат.
Имелось ввиду что-то типа максимума результата при минимуме затрат.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099034
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ФиллипТак ты ему поясни что он козёл отмороженный...
Не понял почему козел отмороженный?
Ведь в PB на самом деле есть GC.
Я вот тоже destroy не пользуюсь, т.к. если мне сказали что есть сборщик мусора, который уничтожает объекты, на которые нет ссылок, так я считаю, что следить за памятью не моя проблема, а проблема pbvm.
Может просветите в чем проблема, почему необходимо уничтожать объекты, которые созданы руками?
Думаю не только мне это будет интересно, еще народ есть, который не пользуется destroy (мой начальник тоже destroy не пользуется и меня так научил :-) ).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099037
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На кнопке висит код:
Код: plaintext
1.
2.
3.
4.
DataStore lds = create DataStore
lds.DataObject = 'd_1'
lds.SetTransObject(SQLCA)
lds.Retrieve()
загружается много-много данных.
Смотрю через TaskManager: приложение занимает 10MB, нажимаю кнопку - идет ретрив - использование памяти увеличивается на 80 MB, как только выходит из обработчика - память возвращается в исходное положение (10MB).
Т.е. GC сработал и грохнул DataStore со всеми данными, т.е. память освободилась.
(честно говоря проделал такую операция, как только первый раз сел за PB и мне сказали, что тут GC есть).
К тому же есть большое финансовое приложение (пишем его 3 года), в котором нет ниодного destroy и ни разу не возникали проблемы с памятью: никаких утечек.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099080
Фотография Ursego
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё это верно. Но вот я привык за много лет дестроить всё, что накриэйтил, и чувствую себя неуютно полагаясь на GC (как было приказано начальством), хотя в современных языках вообще нету команды освобождения память. И это правильно - зачем отвлекаться на мелочи?
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099636
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересноМожет просветите в чем проблема, почему необходимо уничтожать объекты, которые созданы руками?

GC работает асинхронно. Поэтому возможны (и практически существуют) ситуации когда в цикле создаются объекты, а освобождение памяти происходит в конце цикла. При достаточно большом кол-ве итераций возникнет переполнение.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099706
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyGC работает асинхронно. Поэтому возможны (и практически существуют) ситуации когда в цикле создаются объекты, а освобождение памяти происходит в конце цикла. При достаточно большом кол-ве итераций возникнет переполнение.
Причем на своем компьютере с 1 ГБ памяти это будет работать прекрасно, а у пользователя с 256 МБ программа будет падать.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099814
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я конечно понимаю, что можно привести массу конкретных примеров, где предпочтительнее явный destroy, я сам, разумеется, иногда использую destroy, особенно там, где это касается sharedobject.
Но я всё-таки имею ввиду общие случаи.
На счет цикла. GC работает ассинхронно, но у него есть некий период работы, и, мне кажется, что он успеет освободить память, до того как она кончится. (Контрпример в студию).
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099867
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересноНа счет цикла. GC работает ассинхронно, но у него есть некий период работы, и, мне кажется, что он успеет освободить память, до того как она кончится. (Контрпример в студию).
Вы думаете, а я с таким сталкивался. И то, я всегда пишу DESTROY, а тут забыл - и вылезло.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099940
Dim2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк wrote:

> Причем на своем компьютере с 1 ГБ памяти это будет работать прекрасно

Это самое главное .
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099956
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, про цикл убедили. Тут я согласен, что предпочтительнее вызвать destroy.
Но я всё-таки считаю, что в общем случае destroy не нужен.
GC на то и сделан, чтобы снять с программиста задачу управления памяти, кроме этого destroy ведь несколько усложняет код, где есть несколько точек выхода.
Например такой код мне нравится больше:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
uo_1 obj1, obj2
obj1 = create uo_1
obj2 = create uo_2
...
if (...) then return
if (...) then return
if (...) then return
if (...) then return
...
do while (...)
   do while (...)
      ...
   loop
loop
...
return
чем этот:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
uo_1 obj1, obj2
obj1 = create uo_1
obj2 = create uo_2
...
if (...) then
   if (...) then
      if (...) then
         if (...) then
            ...
            do while (...)
               do while (...)
                     ...
               loop
            loop
            ...
         end if
      end if
   end if
end if
...
destroy obj1
destroy obj2
return
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35099980
Фотография Ikar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересно...
кроме этого destroy ведь несколько усложняет код, где есть несколько точек выхода.
...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
TRY
  create object
  ...
  ...
  if ... then return
  ...
  do while ...
    ...
    if ... then return
  loop
  ...
  if ... then return
  ...
FINALLY
  destroy object
END TRY
И никаких усложенний (",)
------------
С уважением, IKAR

IkarHomeCenter ........ Детский Дворик ........ ГавГав.Инфо
Портал русскоязычной группы пользователей Sybase
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100008
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем меня никто не убедил, что всегда надо писать destroy.
Мне кажется, что те, кто пишет destroy, просто привыкли следить за памятью, и пишут его на всякий пожарный.
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100031
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ikar
Код: plaintext
1.
2.
3.
4.
5.
6.
TRY
  create object
  if ... then return
FINALLY
  destroy object
END TRY

ИМХО, после return не вызываются FINALLY
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100057
Интересно
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вызывается 100%
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100087
Фотография Ikar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky...
ИМХО, после return не вызываются FINALLY
На кнопку код:
Код: plaintext
1.
2.
3.
4.
5.
try
	return
finally
	messagebox('', 'finally')
end try
И попробовать (",)
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100858
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ikar Anatoly Moskovsky...
ИМХО, после return не вызываются FINALLY
попробовать
Верю, у меня наверно ложная память сработала :))
...
Рейтинг: 0 / 0
Праграмист, пешы красива!
    #35100898
Oleg1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
интересноВообщем меня никто не убедил, что всегда надо писать destroy.
Мне кажется, что те, кто пишет destroy, просто привыкли следить за памятью, и пишут его на всякий пожарный.DESTROY можно не использовать там, где он автоматом вызывается сразу в момент исчезновения последней ссылки на объект. Во всех случаях лучше использовать. Вообще-то все это пишется на автомате и подобных проблем не возникает.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Праграмист, пешы красива!
    #35887288
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Намедни довелось править какую-то старую програмку. Открываю скрипт и вижу это чудо (см. картинку). Остроумно написано, не правда ли? :)
Праграмист, пешы красива! :):):)
...
Рейтинг: 0 / 0
98 сообщений из 98, показаны все 4 страниц
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Праграмист, пешы красива!
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]