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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.06.2017, 15:26   #121  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от ax_mct Посмотреть сообщение
Что эти аттрибуты, что идея с anytype - это чужеродные отягощающие систему элементы без какой-либо практической пользы.
Атрибуты решают вполне конкретную задачу - добавление нового класса в иерархию без изменения родительского класса, что особенно актульно в 7ке, т.к. не надо оверлеить.
Паттерны из GoF и подобная литература решает конкретную задачу в программировании и очень жалко что по историческим причинам в АХ попадают люди предпочитающие методы по 2000 строк потому что "все в 1 месте, так удобней" и отрицающие все что "не как в 4ке". Выглядит как-то так
За это сообщение автора поблагодарили: ena_ax (-1).
Старый 12.06.2017, 17:16   #122  
ax_mct is offline
ax_mct
Banned
 
2,548 / 1091 (0) ++++++++
Регистрация: 10.10.2005
Адрес: Westlands
Цитата:
Сообщение от skuull Посмотреть сообщение
Атрибуты решают вполне конкретную задачу - добавление нового класса в иерархию без изменения родительского класса, что особенно актульно в 7ке, т.к. не надо оверлеить.
Паттерны из GoF и подобная литература решает конкретную задачу в программировании и очень жалко что по историческим причинам в АХ попадают люди предпочитающие методы по 2000 строк потому что "все в 1 месте, так удобней" и отрицающие все что "не как в 4ке". Выглядит как-то так
Мама там на картинке - права. На велосипеде с каменными колесами далеко не уедешь.

Эти аттрибуты даже не паттерн - это костыль. Причем кривой. Да, решает задачу.
Искусственной проблемы.

Есть фундаментальные правила конкретной системы основанные на изменении слоев.
Best Practices for Static Construct Methods
https://msdn.microsoft.com/en-gb/library/aa637432.aspx

Даже если отставить в сторону вопрос идиотизма блокирования и принять extension model как данность то не такие костыли нужны системе, а многое другое, в частности переопределение и замена статических методов включая ::construct.

Да, получатся те же слои только сбоку, что конечно же противоречит новой религии доступа к телу. Но детей делать не трогая - средневековье. Да, красивые балахоны с дырочками - это конечно решает задачу. Религиозную.
Старый 12.06.2017, 18:50   #123  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от ax_mct Посмотреть сообщение
Мама там на картинке - права. На велосипеде с каменными колесами далеко не уедешь.

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

Последний раз редактировалось skuull; 12.06.2017 в 19:03.
Старый 12.06.2017, 20:40   #124  
ax_mct is offline
ax_mct
Banned
 
2,548 / 1091 (0) ++++++++
Регистрация: 10.10.2005
Адрес: Westlands
Цитата:
Сообщение от skuull Посмотреть сообщение
Есть какие-то "общепринятые" вещи в программировании, про Барбару Стрейзанд Лисков тут уже вспоминали, есть еще Принцип открытости/закрытости. Тоже наверно искусственный принцип. Некоторые даже скажут, что знание этих принципов категорически мешает на внедрениях, ведь удорожает поддержку кода и его усложняет.
Нет "общепринятых" вещей в программировании. Есть те которые приняты в конкретном фрэйморке, продукте, платформе. То есть уместны.

Я до сих пор помню глаза напарника индуса когда завернул Java в X++. И помню свои крепкие матюги на "общепринятые" вещи от блистательного программиста C#.

Да, "общепринятые" вещи в программировании - абсолютно не нужны так как это удорожает поддержку кода и его усложняет.
Любое уровня ERP должно быть максимум консерватизма и максимум последовательности своим основам. Никаких "общепринятых" вещей.

Применительно к Аксапте, запрету overlayering и костылям в виде этих аттрибутов - если это следование "общепринятым" вещам в программировании то кто-то проклял всех программистов, а программистов AX в особенности.

Я вижу Extension model для AX как просто запрет на программирование. Если же это таки альтернатива то она существенно дороже и намного опаснее чем overlayering.
Создание наследников через атрибуты чтобы следовать Extension model - это способ лечения зуба когда рот зашит.

Цитата:
При́нцип откры́тости/закры́тости (англ. The Open Closed Principle, OCP) — принцип ООП, устанавливающий следующее положение: «программные сущности (классы, модули, функции и т. п.) должны быть открыты для расширения, но закрыты для изменения»
Принципов так много что лучше использовать только один - здравый смысл.
За это сообщение автора поблагодарили: dech (3), kvan (3), axotnik88 (1).
Старый 13.06.2017, 05:18   #125  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от fed Посмотреть сообщение
. Если бизнес-процесс описан правильно, то и код не будет выглядеть как набор примеров из Gang Of Four. Классический пример - это архитектура Source Document/Distribution/Subledger. Скорее всего, он просто какой-то бред в спецификации написал, или вы просто половины требований не поняли...
Ну кстати есть более простой пример. метод systemDateGet() объявили устаревшим, а вместо него сейчас везде используют конструкцию DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());.
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс
т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача
Старый 13.06.2017, 07:51   #126  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от trud Посмотреть сообщение
Ну кстати есть более простой пример. метод systemDateGet() объявили устаревшим, а вместо него сейчас везде используют конструкцию DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());.
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс
Где там "создать класс"? Тут два вызова, возращающих примитивы был один.

Цитата:
т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача
Идея была в том, чтобы заставить разработчиков подумать, в какой временной зоне у них дата (что с учетом работы в облаке, например, или другой временной зоны получателя этой информации может быть нетривиально).
Старый 13.06.2017, 07:54   #127  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от trud Посмотреть сообщение
Ну кстати есть более простой пример. метод systemDateGet() объявили устаревшим, а вместо него сейчас везде используют конструкцию DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());.
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс
т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача
В AX 2.5 не было понятия таймзоны. Все работали по времени AOS'а. Напомню, что по этой причине не рекомендовалось использовать функцию today(). Вам никто не мешает создать кастомную функцию Global::xx_today(), которая будет понятна, прозрачна, корректна и безошибочна. хх - префикс вашей компании-разработчика.
__________________
// no comments
За это сообщение автора поблагодарили: belugin (2).
Старый 13.06.2017, 09:14   #128  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от fed Посмотреть сообщение
Поэтому для меня использование в X++ коде слишком большого числа паттернов говорит о том что бизнес-проблема изначально неправильно сформулирована. Если бизнес-процесс описан правильно, то и код не будет выглядеть как набор примеров из Gang Of Four.
Хотелось бы обоснование того, что паттерны это сложно. По моему опыту есть более и менее простые. И некоторые паттерны (типа "фасад") наоборот делают код проще. И еще, если их не знать они все равно будут, просто вразнобой и под несогласованными названиями.

Цитата:
Классический пример - это архитектура Source Document/Distribution/Subledger. Изначально безумный набор бизнес-требований привел к еще более безумной архитектуре.
Тут наверное интересно было бы открыть свою тему про сабледжеры (можно сделать рефакторинг ExtractTopic и перенести сообщения fed ). Я вижу своей программисткой кочки там скорее попытку обобщить логику финансовой разноски. Дополнительных требований там не так много.
Старый 13.06.2017, 09:28   #129  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,890 / 5647 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от belugin Посмотреть сообщение
Хотелось бы обоснование того, что паттерны это сложно. По моему опыту есть более и менее простые. И некоторые паттерны (типа "фасад") наоборот делают код проще. И еще, если их не знать они все равно будут, просто вразнобой и под несогласованными названиями.
Речь строго говоря не о паттернах, а о том что в бизнес-автоматизации вообще не так уж много сложных алгоритмов. И если тебе не удается алгоритм, грубо говоря, в рамках C++ 1.0 относительно наглядно выразить, скорее речь идет о ситуации неправильно сформулированной спецификации. Просто паттерны в большинстве случаев просто позволяют несколько повысить уровень абстракции и за счет этого более наглядно и обозримо сформулировать сложные алгоритмы, которые на уровне C++ 1.0 наглядно не формируются. Но - как я уже сказал - в бизнес-автоматизации сложных алгоритмов не бывает, в противном случае - они бы не смогли бы быть реализованы как бизнес-процессы.

Пожалуй единственное место в Аксапте, которое, на мой взгляд, просится на переписывание на интерфейсы, фабрики, и тд и тп - это сводное планирование. Там как раз достаточно простой и наглядный общий алгоритм теряется за сотнями специальных случаев. Если бы его создатели смогли его как-то растащить на множество более простых сущностей, алгоритм был бы более читаем и расширяем.

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

Последний раз редактировалось fed; 13.06.2017 в 09:55.
Старый 13.06.2017, 09:52   #130  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от belugin Посмотреть сообщение
Идея была в том, чтобы заставить разработчиков подумать, в какой временной зоне у них дата (что с учетом работы в облаке, например, или другой временной зоны получателя этой информации может быть нетривиально).
Так вот об этом то и речь. т.е. зачем нагружать разработчика бесполезными размышлениями о технических вещах. в пользовательской спецификации на разработку всегда будет одно понятие дата. она может быть на стороне сервера(это systemDateGet() и на стороне клиента today()). Зачем разработчику часовые пояса и их инициализация?
т.е. новую функцию создать то не проблема, но хотелось бы чтобы все шло из коробки(уже созданное, продуманное что когда и как использовать - т.е. собственно было четкое бест-практис правило - поскольку все разноски идут systemDateGet() то надо всегда использовать ее), а не заниматься созданием базовых библиотек

Последний раз редактировалось trud; 13.06.2017 в 10:05.
Старый 13.06.2017, 12:46   #131  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от fed Посмотреть сообщение
Просто паттерны в большинстве случаев просто позволяют несколько повысить уровень абстракции и за счет этого более наглядно и обозримо сформулировать сложные алгоритмы, которые на уровне C++ 1.0 наглядно не формируются. Но - как я уже сказал - в бизнес-автоматизации сложных алгоритмов не бывает, в противном случае - они бы не смогли бы быть реализованы как бизнес-процессы.
Я бы сказал, что в аксапте есть грандиозная структурная сложность за счет отсутсивя модульности - понять что за код и на что он влияет довольно трудно. Пости все есть интерфейс, нигде не гарантируется что в коде одного модуля не может быть вставки из другого модуля.

Разбираться с прикладным кодом достаточно сложно.

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

К тому же такая фабрика помогает достичь модульности.

К сожалению, тут есть часть недостатков:
- нет визуализации соотвествия ключ-класс
- нет контроля целостности во время компиляции (case в Ax7 проверяется на недублирование ключей в дизайн тайме, правда в Ax6 этого не было, как и рантайма тоже - моя попытка сделать статический анализ выгребла ~30 всяких ошибок, часть из которых были свитчи )
- она медленнее

С кодом не использующим патернов может быть сложее разбираться - при работе с прикладным кодом аксапты часто хочется тул, который сравнивает два выделенных куска, чтобы понять, в чем тут разница.
Старый 13.06.2017, 12:58   #132  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от trud Посмотреть сообщение
бесполезными размышлениями о технических вещах. в пользовательской спецификации на разработку всегда будет одно понятие дата.
Это не техническая а логическая вешь. Предположим, что вы из Москвы пишете от руки платежное поручение банку в Нью Йорке - какая там должна быть дата платежа.
Старый 13.07.2017, 22:13   #134  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от skuull Посмотреть сообщение
Атрибуты решают вполне конкретную задачу - добавление нового класса в иерархию без изменения родительского класса, что особенно актульно в 7ке, т.к. не надо оверлеить.
Паттерны из GoF и подобная литература решает конкретную задачу в программировании и очень жалко что по историческим причинам в АХ попадают люди предпочитающие методы по 2000 строк потому что "все в 1 месте, так удобней" и отрицающие все что "не как в 4ке". Выглядит как-то так
А кто сказал, что в 4-ке нельзя сделать иерархию без изменения родительского класса?
Создаём базовый класс:
X++:
public class PPO_Base
{
}

protected void new()
{
}

public str getType()
{
    return "Base";
}

public static PPO_Base construct(IdentifierName _className = classstr(PPO_Base))
{
    DictClass       dictClass   = new DictClass(classname2id(_className));
    ;

    if (!dictClass)
        throw error(strfmt("Unable to instantiate \"%1\" class", _className));

    return dictClass.makeObject();
}

public static void main(Args _args)
{
    IdentifierName  className   = _args ? _args.parm() : classstr(PPO_Base);
    PPO_Base        instance    = PPO_Base::construct(className);
    ;

    info(strfmt("Class type: %1", instance.getType()));
}
А потом делаем сколько угодно наследников:
X++:
public class PPO_Derived extends PPO_Base
{
}

public str getType()
{
    return "Derived";
}
Создаем менюайтемы для каждого класса. В строковом параметре пишем имя класса. (Для базового класса параметр может быть пустым). Если сильно надо, можно создать енум для иерархии, но необходимости нет, имхо.
Как использовать в коде:
X++:
PPO_Base    base    = PPO_Base::construct();
PPO_Base    derived = PPO_Base::construct(classstr(PPO_Derived));
;

info(strfmt("Base class type: %1", base.getType()));
info(strfmt("Derived class type: %1", derived.getType()));
__________________
// no comments
За это сообщение автора поблагодарили: macklakov (1), skuull (2), ax_mct (3), ta_and (4), Logger (1).
Старый 14.07.2017, 04:10   #135  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от dech Посмотреть сообщение
А кто сказал, что в 4-ке нельзя сделать иерархию без изменения родительского класса?
А кто сказал что нельзя? Я сказал что не принято. Оно ж примерно на атрибутах так и работает, просто ненадо свой конструктор каждый раз писать.
А в этой реализации было бы неплохо проверить, что _className являеться наследником базовго класса и getType() у вас вышел какой-то бесполезный, только инфо показывать
Старый 14.07.2017, 10:09   #136  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от skuull Посмотреть сообщение
А кто сказал что нельзя? Я сказал что не принято. Оно ж примерно на атрибутах так и работает, просто ненадо свой конструктор каждый раз писать.
А в этой реализации было бы неплохо проверить, что _className являеться наследником базовго класса и getType() у вас вышел какой-то бесполезный, только инфо показывать
  1. Вместо Construct() можно запилить всего одну глобальную функцию
  2. Это учебный пример, лишнего не писал для ясности
  3. Любой каприз за ваши деньги
__________________
// no comments
Старый 15.07.2017, 12:00   #137  
ta_and is offline
ta_and
Участник
 
226 / 122 (5) +++++
Регистрация: 26.02.2002
Адрес: СПб
Цитата:
Сообщение от dech Посмотреть сообщение
  1. Вместо Construct() можно запилить всего одну глобальную функцию
Да да! и на вход Аргс! )))
За это сообщение автора поблагодарили: ax_mct (3).
Старый 16.07.2017, 13:27   #138  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от ta_and Посмотреть сообщение
Да да! и на вход Аргс! )))
А зачем вам Args, если требуется только создать нужный инстанс?
__________________
// no comments
Старый 16.07.2017, 16:59   #139  
ta_and is offline
ta_and
Участник
 
226 / 122 (5) +++++
Регистрация: 26.02.2002
Адрес: СПб
Цитата:
Сообщение от dech Посмотреть сообщение
А зачем вам Args..?
Каждому инстансу - по параметру! )
Мы же не рассматриваем сферического коня в вакууме, которому совсем параметры не нужны?..
Старый 16.07.2017, 17:09   #140  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от ta_and Посмотреть сообщение
Каждому инстансу - по параметру! )
Мы же не рассматриваем сферического коня в вакууме, которому совсем параметры не нужны?..
X++:
public static void main(Args _args)
{
    IdentifierName  className   = _args ? _args.parm() : classstr(PPO_Base);
    PPO_Base        instance    = PPO_Base::construct(className);
    ;

    instance.parmRecord(_args.record()); // а так можно?
    instance.parmArgs(_args);            // или вот так?

    info(strfmt("Class type: %1", instance.getType()));
}
P.S. Кажется уже был разговор о том, что в new()/makeObject() нельзя передавать параметры, если класс планируется вызывать в пакете.
__________________
// no comments

Последний раз редактировалось dech; 16.07.2017 в 17:14.
За это сообщение автора поблагодарили: macklakov (5).
Теги
sysextension framework, sysoperation framework, как правильно, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
stephenmann: Technical History of Dynamics AX - From Axapta 3.0 to AX2012 Blog bot DAX Blogs 5 03.03.2017 10:22
dynamicsax-fico: Invoice search AX2012 vs. AX7 (Part 2) Blog bot DAX Blogs 0 01.04.2016 10:11
DAX2009 аналог friend классов. Как сделать? Raven Melancholic DAX: Программирование 9 07.11.2015 23:50
emeadaxsupport: Inventory closing differences between AX4.0 and AX2012 using weighted average costing method Blog bot DAX Blogs 0 27.12.2012 19:11
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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