AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.06.2017, 10:26   #1  
trud is offline
trud
Участник
 
374 / 239 (8) ++++++
Регистрация: 07.06.2003
ну или вот еще пример "правильной" архитектуры. т.е. сейчас чтобы создать диалог с кнопкой выбрать файл надо написать 60 строк кода
**** mazzy: выделено отсюда AX2012. Цель атрибутов в расширении наследования классов *****

ну или вот еще пример "правильной" архитектуры. т.е. сейчас чтобы создать диалог(неважно RunBase или Operation) с кнопкой выбрать файл надо написать 60 строк кода(пример ERFileImportUIBuilder, ERImportFormatDataSourceContractUIBuilder или порядка десятка стандартных классов runBase т.е в каждом классе добавляется один и тот же код для этого.
Плюс еще зашиться на то, что кнопка ОК в диалоге называется 'CommandButton' (т.е. если кто-то переименует ее на что-то более внятное, то все это вмиг перестанет работать)
т.е. тут наверное тоже хотели заставить прикладного разработчика думать что это тебе тут не просто выбрать файл, а куча работы с передачей кучи параметров.
но все же сравните с ранним подходом - когда достаточно было добавить в диалог тип FileNameOpen и все сразу работало
Миниатюры
Нажмите на изображение для увеличения
Название: OkButton.jpg
Просмотров: 4
Размер:	98.2 Кб
ID:	11490  

Последний раз редактировалось mazzy; 14.06.2017 в 15:26.
Старый 13.06.2017, 13:24   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от trud Посмотреть сообщение
ну или вот еще пример "правильной" архитектуры. т.е. сейчас чтобы создать диалог
Вы весьма верно описали проблему, но с анализом причин я несогласен. В данном случае

- конкретный девелопер скопипастил, вместо того, чтобы отрефакторить.
- Класс dialog (который был и раньше) не предоставляет доступ к enable/disable для кнопки OK. (Кстати, в коде для Ax3 насколько я помню тоже был поиск контролов по именам для диалоговых классов - поправьте, если не прав)
- приведите, пожалуйста код с той же функциональностью для автоматической загрузки файла с клиента на сервер? Насколько там меньше кода и за счет чего?
За это сообщение автора поблагодарили: mazzy (2).
Старый 13.06.2017, 13:55   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2014
 
2,807 / 1453 (54) ++++++++
Регистрация: 12.10.2004
Цитата:
Сообщение от belugin Посмотреть сообщение
- Класс dialog (который был и раньше) не предоставляет доступ к enable/disable для кнопки OK
...
- приведите, пожалуйста код с той же функциональностью для автоматической загрузки файла с клиента на сервер? Насколько там меньше кода и за счет чего?
Зачем подменять обсуждаемый вопрос ?
В подавляющем большинстве случаев дизейбл/инейбл кнопки Ok для пакетников не нужен.
Автоматическая загрузка тут не в тему. Речь вообще была не про нее.
По-моему пример как раз очень красноречив. Зачем проектировать фреймворк так, чтобы для элементарного действия надо было написать кучу строк кода. Особенно прикольно смотрится, когда в старом фреймворке можно было одной строчкой обойтись.

Последний раз редактировалось Logger; 13.06.2017 в 14:34. Причина: поправил опечатки
За это сообщение автора поблагодарили: trud (1), ax_mct (5), mazzy (2).
Старый 13.06.2017, 14:45   #4  
trud is offline
trud
Участник
 
374 / 239 (8) ++++++
Регистрация: 07.06.2003
ну т.е. да. не знает пользователь ничего про "проблемы передачи файла с клиента на сервер". и про временное хранилище на azure не знает. да и не должен знать
пользователь ставит задачу по простому- дай мне выбрать файл и обработай его.
т.е. идеально программа так и должна выглядеть- объявить переменную для отображения файла(с возможностью задать пару параметров(такие как расширение и прочее), написать код для обработки

сейчас предлагается объявить класс для реализации стратегии временного хранения(указать кол-во минут после которой файл станет экспайред - кстати тут вообще треш- это прописывается в классе, и непонятно руководствуясь чем прикладной разработчик должен выбирать это время - во многих местах 5мин, в банковской выписке 60 мин), передать его в другой класс - в виде строки, как classStr - это тоже "красиво" конечно, я так понимаю идет эмуляция атрибутов(возвращаясь с исходной теме), создать евент для дизейблинга кнопки ОК на время загрузки, подключить этот евен к событию окончания загрузки файла, снять это событие после окончания загрузки, не забыть еще удалить этот файл из временного хранилища и прочее - и такое повторяется во всех 10-15 классах в стандарте где используется загрузка файлов в диалоге

т.е. какие-то бизнес функции подменяются техническими абстракциями

а кстати есть ли название у такого подхода с передачей класса, это из какого-то существующего языка?
т.е. код вида
X++:
Class1 c1 = new Class1();

c1.init(classstr(Class2));

Последний раз редактировалось trud; 13.06.2017 в 14:54.
Старый 13.06.2017, 17:37   #5  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
1,524 / 473 (19) +++++++
Регистрация: 10.10.2005
Адрес: PHP
Цитата:
Сообщение от trud Посмотреть сообщение
а кстати есть ли название у такого подхода с передачей класса, это из какого-то существующего языка?
т.е. код вида
X++:
Class1 c1 = new Class1();

c1.init(classstr(Class2));
Весь изврат идет от эльфов, то есть Java-истов.
Похоже на Class.forName("fully qualified class name") когда используют рефлексию для регистрации именно конкретного класса в фабрике. Очень кстати близко к использованию атрибутов для наследования.

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

Что ведь раздражает программистов положивших на Аксапту лет по 10? Неуважение к Аксапте и ее правилам.

В Java надо программировать как на Java, в X++ как в AX, в PHP - как положено в конкретном фрэймворке. А не как "общепринято".

P.S. По ходу я сам далеко не священник Best Practices в AX то есть позволяю себе отступления от них. Но на базе опыта и осознанно.
Основной критерий - практичность и понятность. Когда мне хочется писать как на Java - я тупо себя останавливаю. Так как это программистское бешенство если вне родной среды.

Последний раз редактировалось ax_mct; 13.06.2017 в 17:50.
За это сообщение автора поблагодарили: gl00mie (2).
Старый 13.06.2017, 18:39   #6  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Зачем подменять обсуждаемый вопрос ?
Я вроде честно обсуждал по пунктам, как я понимаю

Цитата:
В подавляющем большинстве случаев дизейбл/инейбл кнопки Ok для пакетников не нужен.
Он там не был необходим - просто защита от того, что пользователь не загрузит файл и нажмет OK. Наверное контрол не поддерживал mandatory или может и сейчас не поддерживает.

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

Поправьте меня, если я напутал.

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

Последний раз редактировалось belugin; 13.06.2017 в 18:49.
За это сообщение автора поблагодарили: mazzy (20).
Старый 13.06.2017, 18:48   #7  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от trud Посмотреть сообщение
а кстати есть ли название у такого подхода с передачей класса, это из какого-то существующего языка?
т.е. код вида
X++:
Class1 c1 = new Class1();

c1.init(classstr(Class2));
В основном в X++ - так как было принято решение, что можно объявить класс с таким же именем что и переменную, то класс не является именем объекта-метакласса, как в Питоне, например, а надо специально его объявлять с такой штукой. Да и тип у нее - строка

В С# передают type а не строчку.
В X++ - tableNum, fieldNum, classStr, tableStr и т.д. то есть передаются целые числа и строки без контроля типов.
Старый 13.06.2017, 19:26   #8  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
1,524 / 473 (19) +++++++
Регистрация: 10.10.2005
Адрес: PHP
Цитата:
Сообщение от belugin Посмотреть сообщение
В основном в X++ - так как было принято решение, что можно объявить класс с таким же именем что и переменную, то класс не является именем объекта-метакласса, как в Питоне, например, а надо специально его объявлять с такой штукой. Да и тип у нее - строка

В С# передают type а не строчку.
В X++ - tableNum, fieldNum, classStr, tableStr и т.д. то есть передаются целые числа и строки без контроля типов.
Что X++, что Java, что С# - все это делают. По сути - рефлексия. Которая не сильно уместна в коде приложения, а больше для утилит.

X++
SysDictClass::newName(classstr("class name"));

С#
Assembly.CreateInstance("class name");

Java
Class.forName("class name")

А код типа
Class1 c1 = new Class1();
c1.init(classstr(Class2));
если подумать то полная дичь, а не рефлексия. Дали конкретной обезьяне зачем-то знание паттернов.
Старый 13.06.2017, 19:57   #9  
dech is offline
dech
Участник
Аватар для dech
 
387 / 140 (5) +++++
Регистрация: 25.06.2009
Адрес: Омск
Цитата:
Сообщение от belugin Посмотреть сообщение
В основном в X++ - так как было принято решение, что можно объявить класс с таким же именем что и переменную, то класс не является именем объекта-метакласса, как в Питоне, например, а надо специально его объявлять с такой штукой. Да и тип у нее - строка

В С# передают type а не строчку.
В X++ - tableNum, fieldNum, classStr, tableStr и т.д. то есть передаются целые числа и строки без контроля типов.
Если речь идёт о рефлексии, то что насчет classnum() / classidget()?
Почему про них забыли и никто этим не пользуется?
__________________
// no comments
Старый 13.06.2017, 22:43   #10  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
1,524 / 473 (19) +++++++
Регистрация: 10.10.2005
Адрес: PHP
Цитата:
Сообщение от dech Посмотреть сообщение
Если речь идёт о рефлексии, то что насчет classnum() / classidget()?
Почему про них забыли и никто этим не пользуется?
Потому что с небес спускаются боги от программирования которые знают "общепринятое" classstr() и не знакомы с этими местячковыми функциями. Ну и походу показывают убогим что такое настоящее программирование.

Вот для них и выставляют в качестве интерфейса SysDictClass::newName(class name), чтобы потом стыдливо className2Id() для new(Id).

И да, по-моему эти "атрибуты в расширении наследования классов" - по сути своей ни что иное как использование рефлексии. Патентованный хак заколоченной фабрики.
За это сообщение автора поблагодарили: ta_and (3).
Старый 14.06.2017, 07:18   #11  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от ax_mct Посмотреть сообщение
А код типа
Class1 c1 = new Class1();
c1.init(classstr(Class2));
если подумать то полная дичь, а не рефлексия. Дали конкретной обезьяне зачем-то знание паттернов.
Я думаю тут trud имел ввиду вообще саму идею передачи имени класса, а не то, что это то же имя класса, что и у того объкта, которому он передается
Старый 14.06.2017, 07:29   #12  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от dech Посмотреть сообщение
Если речь идёт о рефлексии, то что насчет classnum() / classidget()?
Почему про них забыли и никто этим не пользуется?
Про них не забыли ими пользуются, но меньше. classIDGet вообще альтернативы пока нет.

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

Соответственно везде перевели хранение на имена. Дополниельно к этому перевели на строчки еще кучу мест - тут уж я не знаю зачем. Например типы в диалоге, вроде, никуда не сохраняются, а addField(typeNum(xxx) надо переводить на extendedTypeStr
За это сообщение автора поблагодарили: ax_mct (5).
Старый 14.06.2017, 11:20   #13  
ta_and is offline
ta_and
Участник
 
170 / 97 (4) ++++
Регистрация: 26.02.2002
Адрес: СПб
Цитата:
Сообщение от belugin Посмотреть сообщение
типы в диалоге, вроде, никуда не сохраняются, а addField(typeNum(xxx) надо переводить на extendedTypeStr
зубная боль...
зачем?..............
За это сообщение автора поблагодарили: ax_mct (5).
Старый 14.06.2017, 15:23   #14  
kashperuk is offline
kashperuk
Senior SDE, Dynamics AX
Аватар для kashperuk
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
 
4,247 / 1910 (72) ++++++++
Регистрация: 30.05.2004
Адрес: Копенгаген, Дания
Цитата:
Сообщение от belugin Посмотреть сообщение
Соответственно везде перевели хранение на имена. Дополниельно к этому перевели на строчки еще кучу мест - тут уж я не знаю зачем. Например типы в диалоге, вроде, никуда не сохраняются, а addField(typeNum(xxx) надо переводить на extendedTypeStr
Этого, кстати, никто не заставляет делать.
Но все новые API используют строковое представление для объектов АОТ, поэтому при написании нового кода или рефакторинге логичнее использовать их.
Старый 14.06.2017, 15:34   #15  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
Most Valuable Professional
 
20,635 / 3261 (150) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Но все новые API используют строковое представление для объектов АОТ, поэтому при написании нового кода или рефакторинге логичнее использовать их.
С моделями плохо получается.
По сути модель в аксапте - это привычный namespace.

название без namespace - не очень.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 14.06.2017, 15:41   #16  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Этого, кстати, никто не заставляет делать.
Как это, не заставляет, если в dialog.addField теперь нельзя запихать TypeID а только TypeName? Все далоги надо обрабатывать хотя бы просто S&R на numStr/extendedTypeStr - обратной совместимости же нет
Старый 14.06.2017, 15:44   #17  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
По сути модель в аксапте - это привычный namespace.
Модель это скорее некая папка - она не создает пространства имен. Имена в разных моделях не могут пересекаться.

Модуль, это сборка. А пространство имен глобальное, общее, одно.
За это сообщение автора поблагодарили: mazzy (2).
Старый 15.06.2017, 06:59   #18  
ta_and is offline
ta_and
Участник
 
170 / 97 (4) ++++
Регистрация: 26.02.2002
Адрес: СПб
Цитата:
Сообщение от belugin Посмотреть сообщение
Все далоги надо обрабатывать хотя бы просто S&R на numStr/extendedTypeStr - обратной совместимости же нет
Вот вот...
Что можно сказать об изменении интерфейсов в базовых классах после их публичной декларации?
Ага.
Только одно.
Тот человек, который ПРИДУМАЛ это решение совершенно не знает ничего о программировании.
Этому человеку совершенно на...ть на всех, кто работал до него.
И на тех, кто будет работать с его "гениальным решением" при переходе с предыдущих версий.
А так как это решение было принято и одобрено видимо не одним человеком, то напрашивается вывод о работе всей команды.
Я очень уважаю M$ как фирму.
Но у меня есть вопросы к некоторым (неизвестным мне) людям, которые работают в этой фирме. один из вопросов - ЗАЧЕМ?
Старый 15.06.2017, 08:47   #19  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,880 / 2004 (74) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от ta_and Посмотреть сообщение
Вот вот...
Что можно сказать об изменении интерфейсов в базовых классах после их публичной декларации?
Ага.
Только одно.
Тот человек, который ПРИДУМАЛ это решение совершенно не знает ничего о программировании.
По разному бывает. Насколько я помню, Python 2.5 print "Hello, world" - это правильный код, в python 2.6 это уже deprected API в Python 3.0 это ошибка.

В Ax соблюдают обратную совместимость в рамках одной версии. Стараются и дальше, но если нет возможности (например, как с хранением classid/typeid) то приходится переделывать.

Я не знаю, зачем переделали именно API dialog, но сам принцип соблюдается далеко не всеми и не всегда - это все набор компромиссов между разными факторами.

Добавим к этому, что до версии 7.0 в Ax не было ключевого слова internal - то есть нельзя было отделить внутренние классы от внешних, фактически каждый класс был API. Сейчас оно есть но массово не используется.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Запросы формы "Выбрать" в Ax 2012 vmokerov DAX: Программирование 3 18.11.2014 14:19
Как из кода сделать запись в DataSource "грязной"? AR® DAX: Программирование 3 25.04.2014 12:07
Перезапуск AOS'ов. Батник (".bat" файл) lev DAX: Администрирование 3 26.02.2013 12:51
Кнопка "Выбрать", как её добавить aao_p DAX: Программирование 6 31.05.2012 13:36
"Инвентаризационный код" в группах инвентаризации и создание строк инвентаризации lev DAX: Функционал 0 11.10.2011 09:49
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 05:01.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.