EITHER FOR ABAP
EITHER FOR ABAP is a design pattern used in ABAP programming to standardize the management of results and errors. This pattern helps in handling operations that can either succeed with a result or fail with an error, which can be of various types.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contents
- Overview
- Pattern Definition
- Method Examples
- Usage Example
Overview
The Either pattern represents the outcome of an operation with two possible results: a successful result (right) or an error message (left). This pattern enhances code readability and error handling by encapsulating results and errors in a consistent manner.
Pattern Definition
The Either pattern provides a structure that can carry two types of values:
- Left: Represents error messages or failure results.
- Right: Represents successful results.
Below is a simplified definition of the zcleither class:
CLASS zcl_either DEFINITION.
PUBLIC SECTION.
" Creates an instance based on a condition
CLASS-METHODS cond
IMPORTING
!condition TYPE boolean " Condition to determine result
!left_value TYPE any " Value for the left (error)
!right_value TYPE any " Value for the right (success)
RETURNING
VALUE(ro_either) TYPE REF TO zcl_either
RAISING
zcx_either_invalid_type. " Exception for invalid types
" Creates an instance with a left value (error)
CLASS-METHODS left
IMPORTING
!value TYPE any " Error result
RETURNING
VALUE(ro_either) TYPE REF TO zcl_either
RAISING
zcx_either_invalid_type. " Exception for invalid types
" Creates an instance with a right value (success)
CLASS-METHODS right
IMPORTING
!value TYPE any " Success result
RETURNING
VALUE(ro_either) TYPE REF TO zcl_either
RAISING
zcx_either_invalid_type. " Exception for invalid types
" Checks if the instance is a left value
METHODS is_left
RETURNING
VALUE(r_boolean) TYPE boolean. " Returns TRUE if left value
" Checks if the instance is a right value
METHODS is_right
RETURNING
VALUE(r_boolean) TYPE boolean. " Returns TRUE if right value
" Retrieves the left value
METHODS get_left
EXPORTING
VALUE(value) TYPE any " Retrieves left value
RAISING
zcx_either_invalid_access. " Exception for invalid access
" Retrieves the right value
METHODS get_right
EXPORTING
VALUE(value) TYPE any " Retrieves right value
RAISING
zcx_either_invalid_access. " Exception for invalid access
ENDCLASS.
Method Examples
Here are some examples of how the zcleither class can be used:
- dividenumbers Method: Divides two numbers and returns the result or an error message if division by zero is attempted.
``abap METHOD dividenumbers. IF ivdenominator = 0. roresult = zcleither=>left( 'Division by zero error' ). ELSE. DATA(lvresult) = ivnumerator / ivdenominator. roresult = zcleither=>right( lvresult ). ENDIF. ENDMETHOD. ``
- fetchdata Method: Retrieves data based on an ID and returns the data or an error message if the ID is invalid.
``abap METHOD fetchdata. IF ivid left( 'Invalid ID' ). ELSE. DATA(lvdata) = 'Fetched Data'. roresult = zcleither=>right( lvdata ). ENDIF. ENDMETHOD. ``
- processorder Method: Processes an order based on the order ID and returns a success or error message.
``abap METHOD processorder. CASE ivorderid. WHEN 1. roresult = zcleither=>right( 'Order processed successfully' ). WHEN 2. roresult = zcleither=>left( 'Order already processed' ). WHEN OTHERS. roresult = zcleither=>left( 'Order not found' ). ENDCASE. ENDMETHOD. ``
- complexoperation Method: Performs a complex operation and handles errors based on the input.
``abap METHOD complexoperation. DATA: lvintermediate TYPE i. IF ivinput left( 'Negative input not allowed' ). ELSEIF ivinput = 0. roresult = zcleither=>left( 'Zero input not valid' ). ELSE. lvintermediate = ivinput 2. roresult = zcleither=>right( lvintermediate ). ENDIF. ENDMETHOD. ``
Usage Example
Here’s an example of how to use the zcleither class in practice:
START-OF-SELECTION.
DATA: lo_example TYPE REF TO zcl_either_example,
lo_result TYPE REF TO zcl_either,
lv_result TYPE i,
lv_error TYPE string.
" Create an instance of the class
lo_example = NEW zcl_either_example( ).
" Test Example-1: divide_numbers
lo_result = lo_example->divide_numbers(
iv_numerator = 10
iv_denominator = 0
).
IF lo_result->is_left( ).
" Retrieve and display the error message
lo_result->get_left( IMPORTING value = lv_error ).
WRITE: / 'Error in divide_numbers:', lv_error.
ELSE.
" Retrieve and display the result
lo_result->get_right( IMPORTING value = lv_result ).
WRITE: / 'Result of divide_numbers:', lv_result.
ENDIF.
" Test Example-2: fetch_data
lo_result = lo_example->fetch_data(
iv_id = 0
).
IF lo_result->is_left( ).
" Retrieve and display the error message
lo_result->get_left( IMPORTING value = lv_error ).
WRITE: / 'Error in fetch_data:', lv_error.
ELSE.
" Retrieve and display the data
lo_result->get_right( IMPORTING value = lv_result ).
WRITE: / 'Data from fetch_data:', lv_result.
ENDIF.
" Test Example-3: process_order
lo_result = lo_example->process_order(
iv_order_id = 2
).
IF lo_result->is_left( ).
" Retrieve and display the error message
lo_result->get_left( IMPORTING value = lv_error ).
WRITE: / 'Error in process_order:', lv_error.
ELSE.
" Retrieve and display the success message
lo_result->get_right( IMPORTING value = lv_error ).
WRITE: / 'Success message from process_order:', lv_error.
ENDIF.
" Test Example-4: complex_operation
lo_result = lo_example->complex_operation(
iv_input = 5
).
IF lo_result->is_left( ).
" Retrieve and display the error message
lo_result->get_left( IMPORTING value = lv_error ).
WRITE: / 'Error in complex_operation:', lv_error.
ELSE.
" Retrieve and display the result
lo_result->get_right( IMPORTING value = lv_result ).
WRITE: / 'Result of complex_operation:', lv_result.
ENDIF.
Feel free to adjust these suggestions based on your specific needs or the context of your project!