12.06.2017, 15:26 | #121 |
Участник
|
Цитата:
Паттерны из GoF и подобная литература решает конкретную задачу в программировании и очень жалко что по историческим причинам в АХ попадают люди предпочитающие методы по 2000 строк потому что "все в 1 месте, так удобней" и отрицающие все что "не как в 4ке". Выглядит как-то так |
|
|
За это сообщение автора поблагодарили: ena_ax (-1). |
12.06.2017, 17:16 | #122 |
Banned
|
Цитата:
Сообщение от 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; 12.06.2017 в 19:03. |
|
12.06.2017, 20:40 | #124 |
Banned
|
Цитата:
Сообщение от 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 |
Участник
|
Цитата:
Сообщение от fed
. Если бизнес-процесс описан правильно, то и код не будет выглядеть как набор примеров из Gang Of Four. Классический пример - это архитектура Source Document/Distribution/Subledger. Скорее всего, он просто какой-то бред в спецификации написал, или вы просто половины требований не поняли...
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача |
|
13.06.2017, 07:51 | #126 |
Участник
|
Цитата:
Сообщение от trud
Ну кстати есть более простой пример. метод systemDateGet() объявили устаревшим, а вместо него сейчас везде используют конструкцию DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());.
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс Цитата:
т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача
|
|
13.06.2017, 07:54 | #127 |
Участник
|
Цитата:
Сообщение от trud
Ну кстати есть более простой пример. метод systemDateGet() объявили устаревшим, а вместо него сейчас везде используют конструкцию DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone());.
т.е. чтобы получить текущую дату(можно сказать простейшая базовая задача) нужно по сути создать класс, передав туда другой класс т.е. казалось бы - создай одну функцию - текущая дата пользователя, помести туда эту конструкцию из 2 классов и пусть все юзают ее(в одно слово), но видно это какая-то нерешаемая в архитектурном плане задача
__________________
// no comments |
|
|
За это сообщение автора поблагодарили: belugin (2). |
13.06.2017, 09:14 | #128 |
Участник
|
Цитата:
Цитата:
Классический пример - это архитектура Source Document/Distribution/Subledger. Изначально безумный набор бизнес-требований привел к еще более безумной архитектуре.
|
|
13.06.2017, 09:28 | #129 |
Moderator
|
Цитата:
Пожалуй единственное место в Аксапте, которое, на мой взгляд, просится на переписывание на интерфейсы, фабрики, и тд и тп - это сводное планирование. Там как раз достаточно простой и наглядный общий алгоритм теряется за сотнями специальных случаев. Если бы его создатели смогли его как-то растащить на множество более простых сущностей, алгоритм был бы более читаем и расширяем. P.S. Да - можно дискуссию про subledger вытащить куда-нить еще... P.P.S. Еще раз сформулирую - паттерны это не хорошо и не плохо. Паттерны позволяют скрыть сложности реализации и позволяют более наглядно формулировать сложные алгоритмы. Но в большей части бизнес-автоматизации сложных алгоритмов просто не бывает. Поэтому необходимость слишком частого использования паттернов сигнализирует о неправильно постановке задачи. В общем - паттерны - это не болезнь, а симптом... Последний раз редактировалось fed; 13.06.2017 в 09:55. |
|
13.06.2017, 09:52 | #130 |
Участник
|
Цитата:
т.е. новую функцию создать то не проблема, но хотелось бы чтобы все шло из коробки(уже созданное, продуманное что когда и как использовать - т.е. собственно было четкое бест-практис правило - поскольку все разноски идут systemDateGet() то надо всегда использовать ее), а не заниматься созданием базовых библиотек Последний раз редактировалось trud; 13.06.2017 в 10:05. |
|
13.06.2017, 12:46 | #131 |
Участник
|
Цитата:
Сообщение от fed
Просто паттерны в большинстве случаев просто позволяют несколько повысить уровень абстракции и за счет этого более наглядно и обозримо сформулировать сложные алгоритмы, которые на уровне C++ 1.0 наглядно не формируются. Но - как я уже сказал - в бизнес-автоматизации сложных алгоритмов не бывает, в противном случае - они бы не смогли бы быть реализованы как бизнес-процессы.
Разбираться с прикладным кодом достаточно сложно. Во-вторых, на пользовательском уровне такая фабрика проще чем кейз, потому, что она сводит все более простому варианту - "созание по ключу". В case можно напихать в каждый выбор любой логики, соответственно, если знать про то, что должна сделать фабрика, то проще понять, что делает кусок кода. К тому же такая фабрика помогает достичь модульности. К сожалению, тут есть часть недостатков: - нет визуализации соотвествия ключ-класс - нет контроля целостности во время компиляции (case в Ax7 проверяется на недублирование ключей в дизайн тайме, правда в Ax6 этого не было, как и рантайма тоже - моя попытка сделать статический анализ выгребла ~30 всяких ошибок, часть из которых были свитчи ) - она медленнее С кодом не использующим патернов может быть сложее разбираться - при работе с прикладным кодом аксапты часто хочется тул, который сравнивает два выделенных куска, чтобы понять, в чем тут разница. |
|
13.06.2017, 12:58 | #132 |
Участник
|
Это не техническая а логическая вешь. Предположим, что вы из Москвы пишете от руки платежное поручение банку в Нью Йорке - какая там должна быть дата платежа.
|
|
14.06.2017, 15:29 | #133 |
Участник
|
часть обсуждения выделена в отдельную ветку
ну или вот еще пример "правильной" архитектуры. т.е. сейчас чтобы создать диалог с кнопкой выбрать файл надо написать 60 строк кода |
|
13.07.2017, 22:13 | #134 |
Участник
|
Цитата:
Сообщение от skuull
Атрибуты решают вполне конкретную задачу - добавление нового класса в иерархию без изменения родительского класса, что особенно актульно в 7ке, т.к. не надо оверлеить.
Паттерны из GoF и подобная литература решает конкретную задачу в программировании и очень жалко что по историческим причинам в АХ попадают люди предпочитающие методы по 2000 строк потому что "все в 1 месте, так удобней" и отрицающие все что "не как в 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 |
Участник
|
Цитата:
А в этой реализации было бы неплохо проверить, что _className являеться наследником базовго класса и getType() у вас вышел какой-то бесполезный, только инфо показывать |
|
14.07.2017, 10:09 | #136 |
Участник
|
Цитата:
Сообщение от skuull
А кто сказал что нельзя? Я сказал что не принято. Оно ж примерно на атрибутах так и работает, просто ненадо свой конструктор каждый раз писать.
А в этой реализации было бы неплохо проверить, что _className являеться наследником базовго класса и getType() у вас вышел какой-то бесполезный, только инфо показывать
__________________
// no comments |
|
15.07.2017, 12:00 | #137 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: ax_mct (3). |
16.07.2017, 13:27 | #138 |
Участник
|
А зачем вам Args, если требуется только создать нужный инстанс?
__________________
// no comments |
|
16.07.2017, 16:59 | #139 |
Участник
|
|
|
16.07.2017, 17:09 | #140 |
Участник
|
Цитата:
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())); }
__________________
// no comments Последний раз редактировалось dech; 16.07.2017 в 17:14. |
|
|
За это сообщение автора поблагодарили: macklakov (5). |
Теги |
sysextension framework, sysoperation framework, как правильно, полезное |
|
|