ABAP DDD, как правильно реализовать добавление / обновление / удаление дочерних элементов из агрегата через RFC? - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь следовать принципам DDD для моего текущего проекта.К сожалению, мне приходится использовать RFC из-за технических ограничений, поэтому нет OData и REST.Это довольно длинный вопрос, я надеюсь, что это нормально - задавать это в Stackoverflow.

В любом случае у меня есть класс сущности WorkOrder со списком объектов Operation.

У меня есть класс WorkOrderRepository сметод SAVE, который получает только объект WorkOrder и способен сохранять все (данные заголовка, адрес и т. д.) за один раз.Неважно, если это создание, обновление или удаление.Хранилище скрывает вызовы BAPI от остальных.

Теперь я хочу реализовать логику добавления / обновления / удаления операций к объекту рабочего задания, и я не уверен, даже если имена, которые я даю методамверны.Может быть, их следует вставить / отредактировать / удалить ... Я смущен этим, потому что в каждом месте, где я смотрю, используются разные имена.

Но наиболее важны мои два конкретных сомнения:

  1. Должен ли я иметь только 1 RFC, который получает все обновления сущности WorkOrder, включая заголовок, операции?Или я должен создать 1 RFC на операцию, которая обрабатывает только одну операцию за раз?Имейте в виду, что макет пользовательского интерфейса ожидает, что пользователь может добавить / удалить несколько операций перед нажатием кнопки SAVE, а RFC имеет неявную фиксацию, и что, насколько мне известно, сущность DDD должна обновляться всегда за один вызов.

Вариант 1:

FUNCTION ZWORKORDER_HDR_UPD
  IMPORTING
    VALUE(I_WORKORDER_ID) TYPE AUFNR
    VALUE(I_WORKORDER_HDR_CHG) TYPE ZWORKORDER_HDR_CHG
    VALUE(I_WORKORDER_HDR_UPD) TYPE ZWORKORDER_HDR_UPD "X structure for the BAPI
    VALUE(I_OPERATIONS_CHG) TYPE ZOPERATIONS_CHG
    VALUE(I_OPERATIONS_UPD) TYPE ZOPERATIONS_UPD
    VALUE(I_OPERATIONS_DEL) TYPE ZOPERATIONS_DEL
  EXPORTING
    VALUE(E_ERRORS) TYPE BAPIRET2_T.

Вариант 2

FUNCTION ZWORKORDER_OPERATION_CRT
  IMPORTING
    VALUE(I_WORKORDER_ID) TYPE AUFNR
    VALUE(I_OPERATION) TYPE ZOPERATION_CHG
  EXPORTING
    VALUE(E_ERRORS) TYPE BAPIRET2_T.

FUNCTION ZWORKORDER_OPERATION_UPD
  IMPORTING
    VALUE(I_WORKORDER_ID) TYPE AUFNR
    VALUE(I_OPERATION_CHG) TYPE ZOPERATION_CHG
    VALUE(I_OPERATION_UPD) TYPE ZOPERATION_UPD
  EXPORTING
    VALUE(E_ERRORS) TYPE BAPIRET2_T.

  FUNCTION ZWORKORDER_OPERATION_DEL
      IMPORTING
        VALUE(I_WORKORDER_ID) TYPE AUFNR
        VALUE(I_OPERATION_ID) TYPE ZOPERATION_ID
      EXPORTING
        VALUE(E_ERRORS) TYPE BAPIRET2_T.
Как должны выглядеть методы Workorder для этого?Меня особенно смущает метод update, поскольку я не уверен, должен ли я сначала получить существующую операцию, а затем обновить ее или позволить родительскому классу сделать это.Но, возможно, мои подходы совершенно неверны от корня.

Вариант 1:

workorder->add_operation( i_operation ). "Pass flat structure from RFC? Or first create object?
workorder->update_operation( i_operation_chg
                             i_operation_upd ).
workorder->delete_operation( i_operation_id ).

Вариант 2:

workorder->add_operation( ).
operation = workorder->get_operation(i_operation_chg->get_id())
operation->update( i_operation_chg
                   i_operation_upd ).
operation->delete_operation( i_operation_id ).

1 Ответ

0 голосов
/ 25 сентября 2019

Самое простое решение - всегда лучшее (принципы KISS и YAGNI ).На самом деле не имеет значения, создаете ли вы 1 или 3 RFC-функциональных модуля, поэтому, если вы можете достичь своей цели с помощью одного функционального модуля, то сделайте это с одним.

  1. Я думаю,Вам необходимо иметь два функциональных модуля с поддержкой RFC.Один для проверки поддерживаемых операций (выполните проверки насколько это возможно), но это не должно ничего сохранять в базе данных, а другой вызывается после того, как пользователь нажимает кнопку СОХРАНИТЬ, чтобы сохранить весь «WorkOrder», включая поддерживаемые операции.(в это время также будет проведена полная проверка).

  2. Если вам не нужно определять класс «операции» для чего-то другого, прямо сейчас , тогда будьте проще, не нужно создавать экземпляр объекта.Обратите внимание, что вы можете создать класс «операция» с закрытыми статическими методами и быть другом класса «рабочий порядок» (только этот класс может использовать класс операции), просто чтобы лучше организовать свой код.

PS: хотя я не знаю, что такое «доменно-управляемый дизайн», я не понимаю, как с этим связан ваш вопрос, потому что он просто выглядит как простой дизайн программы.

...