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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.07.2019, 05:55   #1  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Паттерн initFrom() на таблице
Друзья, снова может быть ерундой занимаюсь, но все же прошу оценить. Суть паттерна в том, чтобы использовать один единственный метод для инициализации, остальные методы initFrom*() сделать private. С точки зрения пользователя кода это позволит сделать код немного чище и сосредоточиться на задаче не выискивая нужный метод в выпадающем списке. Сами делаем только на кастомных таблицах, используем весьма успешно.
X++:
public void initFrom(Common _common)
{
    switch (_common.TableId)
    {
        case tableNum(SalesLine):
            this.initFromSalesLine(_common);
            break;

        case tableNum(SalesTable):
            this.initFromSalesTable(_common);
            break;

        case tableNum(InventTable):
            this.initFromInventTable(_common);
            break;

        case tableNum(EcoResProduct):
            this.initFromEcoResProduct(_common);
            break;

        case tableNum(WMSBillOfLading):
            this.initFromWMSBillOfLading(_common);
            break;

        default:
            throw error(Error::wrongUseOfFunction(funcName()));
    }
}
__________________
// no comments
Старый 21.07.2019, 10:28   #2  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от dech Посмотреть сообщение
Суть паттерна в том, чтобы использовать один единственный метод для инициализации, остальные методы initFrom*() сделать private.
из минусов:
Будет сложнее использовать перекрестные ссылки, нельзя будет добавить доп. параметры в метод initFromSalesTable.., сложнее работать с кодом и отладчиком
Особых плюсов я не очень вижу
За это сообщение автора поблагодарили: Vadik (1), belugin (3), Logger (3), dech (2).
Старый 21.07.2019, 20:10   #3  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от trud Посмотреть сообщение
из минусов:

Особых плюсов я не очень вижу
Ещё пользователю придется лезть в тело метода чтобы узнать работает ли он с данной конкретной таблицей и компилятор это не будет контролировать.

Т.е. все плюсы статической типизации будут убиты.
За это сообщение автора поблагодарили: dech (2).
Старый 22.07.2019, 12:35   #4  
axm2017 is offline
axm2017
Участник
 
1,748 / 292 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от dech Посмотреть сообщение
Друзья, снова может быть ерундой занимаюсь, но все же прошу оценить. Суть паттерна в том, чтобы использовать один единственный метод для инициализации, остальные методы initFrom*() сделать private..
Почему не захотели сделать с выносом логики на классы типа как в SalesLine к примеру?
Тогда код был бы гибче и возможно красивее.
Старый 26.07.2019, 08:34   #5  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Красивее использовать
X++:
myTable.initFrom(salesLine);
чем
X++:
myTable.initFromSalesLine(salesLine);
чисто из эстетических соображений :-)
А вынос логики только ради этого, считаю, нецелесообразен.
Цитата:
Сообщение от belugin Посмотреть сообщение
Т.е. все плюсы статической типизации будут убиты.
Да, согласен, надо контролировать, что уже есть в методе, чтобы не допустить ошибку Error::wrongUseOfFunction().
__________________
// no comments
Старый 26.07.2019, 08:51   #6  
axm2017 is offline
axm2017
Участник
 
1,748 / 292 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от dech Посмотреть сообщение
Красивее использовать
X++:
myTable.initFrom(salesLine);
Это понятно вопрос в том что внутри initFrom
например там может быть жесткий switch как у вас
а может быть вызов класса обработчика через конструктор где на основе атрибута (где например параметр tableName) собственно и выбирается конкретный обработчик.
В этом случае вам в случае необходимости не надо лазить в табличку и менять в ней код достаточно просто добавлять класс обработчик с соответствующим атрибутом
MyAttr(tableName(newTable)) для примера.
Старый 26.07.2019, 09:11   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от dech Посмотреть сообщение
Красивее использовать
X++:
myTable.initFrom(salesLine);
чем
X++:
myTable.initFromSalesLine(salesLine);
чисто из эстетических соображений :-)
Это называется не "эстетические", а сугубо "личные" предпочтения. Обычная практика, когда привычки, приобретенные в одном языке программирования, "за уши" тащат в другой язык программирования. Просто потому, что "так привык"

В данном случае, любые, т.е. вообще любые аргументы "против" будут сходу отвергаться. Работает же. Чего вам еще надо-то?

Тот факт, что это вообще-то, нарушает уже существующий стиль Axapta - не важно. Тот факт, что другие разработчики будут постоянно "спотыкаться" - не важно. Тот факт, что другие разработчики, скорее всего, создадут копию метода, но уже в привычном стиле initFromXXX - не важно. Тот факт, что метод сложно расширяемый с точки зрения параметров - не важно. И вообще, Best Practices придумали "враги"

Я не вижу ни одной разумной причины так делать, кроме личных предпочтений. И что? Разве это все для Вас аргумент? Нет, конечно! Т.е. сам дискуссия смысла не имеет. Каждый останется при своем мнении
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 26.07.2019 в 09:16.
Старый 26.07.2019, 09:45   #8  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Да, перекрестные ссылки по функциям типа initFromSalesLine сразу придут в плохо воспринимаемый вид. Искать откуда это вызывается придётся дольше.

initFrom с switch-case хорош только в ситуациях когда на входе действительно появляется неизвестный common. Я с такими ситуациями не сталкивался. Наверное потому что не создаю их.
__________________
Дмитрий
За это сообщение автора поблагодарили: dech (1).
Старый 26.07.2019, 11:58   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,427 / 1771 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от dech Посмотреть сообщение
Да, согласен, надо контролировать, что уже есть в методе, чтобы не допустить ошибку Error::wrongUseOfFunction().
Поймать ошибку на уровне компиляции завсегда лучше чем в рантайм. Лично для меня это перекрывает все остальные удобства и недостатки.

Сама по себе логика методов initFrom* понятна. Например, в таблице A есть внешний ключ на таблицу B, и нам этого не достаточно а нужно ещё помимо ссылки сохранить (для истории/для производительности/для гибкости) текущие значения каких-то ещё полей из таблицы B. В таком случае реализуя на таблице A метод initFromB мы создаём некоторую абстракцию, мы позволяем таблице А самой решать какие поля забрать из таблицы B. Если в дальнейшем понадобится изменить состав таких полей, то это можно будет сделать не меняя внешний код.

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

Единственное теоретическое применение обобщённого метода InitFrom, которое приходит в голову - это выполнение каких-то одинаковых действий при инициализации разных полей. Но что это может быть?

Ваш паттерн явно и намеренно нарушает Принцип единственной ответственности (Single Responsibility Principle) - та самая S в известной аббревиатуре SOLID
За это сообщение автора поблагодарили: dech (1).
Старый 26.07.2019, 12:43   #10  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от dech Посмотреть сообщение
Да, согласен, надо контролировать, что уже есть в методе, чтобы не допустить ошибку Error::wrongUseOfFunction().
Так кстати уже не рекомендуется в д365.
Можно кстати переписать шаблон на использование атрибутов и Plugin framework, тогда в нем гарантированно никто не разберется и он будет повышать job security
За это сообщение автора поблагодарили: dech (1).
Старый 26.07.2019, 12:54   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от dech Посмотреть сообщение
чтобы использовать один единственный метод
В Аксапте нужны:
* перегрузка методов
* генерики

без этого лучше использовать традиционный способ
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: dech (1).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Фильтрование записей при "переходе к основной таблице" demID DAX: Программирование 10 18.11.2015 12:52
Аккуратнее! ValidateDelete() на таблице не всегда спасет. Pustik DAX: Программирование 10 16.03.2012 22:40
Переименование полей в одной таблице на основе данных из другой niksen DAX: Программирование 1 14.09.2011 12:34
Переход на правильную запись при Переходе к основной таблице. Anais DAX: Программирование 11 29.06.2004 19:16
фильтр по связанной таблице mick_777 DAX: Программирование 13 21.08.2002 16:00
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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