powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Праграмист, пешы красива!
25 сообщений из 98, страница 1 из 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
25 сообщений из 98, страница 1 из 4
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Праграмист, пешы красива!
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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