Part 1 – Transforming a simple procedural model into its equivalent OO design, focusing on the OO principles of Encapsulation and Abstraction.
Part 2 – Exploring Abstraction further by refactoring the program to transform selected static classes into instantiable classes.
Part 3 – Refactoring the program further to take advantage of the OO principle of Inheritance.
Part 4 – Adhering to the Single Responsibility Principle by refining the program to restrict each class to do only what it is intended to do.
Part 5 – Removing classes that no longer serve a purpose.
Part 6 – Introducing the Singleton OO design pattern, resulting in elimination of all static classes.
report.
interface data_exchangeable.
types : row_counter type n length 02.
types : email_recipient
type adr6-smtp_addr.
endinterface.
class flight_records_retriever definition
abstract
final.
public section.
types : record_list type standard table of sflight.
class-methods: retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type flight_records_retriever=>record_list
.
endclass.
class flight_records_retriever implementation.
method retrieve_records.
select *
into table record_stack
from sflight
up to row_count rows.
endmethod.
endclass.
class carrier_records_retriever definition
abstract
final.
public section.
types : record_list type standard table of scarr.
class-methods: retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type carrier_records_retriever=>record_list
.
endclass.
class carrier_records_retriever implementation.
method retrieve_records.
select *
into table record_stack
from scarr
up to row_count rows.
endmethod.
endclass.
class booking_records_retriever definition
abstract
final.
public section.
types : record_list type standard table of sbook.
class-methods: retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type booking_records_retriever=>record_list
.
endclass.
class booking_records_retriever implementation.
method retrieve_records.
select *
into table record_stack
from sbook
up to row_count rows.
endmethod.
endclass.
class excel_spreadsheet_manager definition
final.
public section.
methods : copy_table_to_excel_worksheet
importing
source_stack
type standard table
source_description
type string
raising
zcx_excel
, send_excel_via_email
importing
recipient
type data_exchangeable=>email_recipient
.
private section.
data : excel type ref to zcl_excel.
endclass.
class excel_spreadsheet_manager implementation.
method copy_table_to_excel_worksheet.
constants : first_column type char1 value 'A'
.
data : worksheet type ref to zcl_excel_worksheet
, worksheet_title
type zexcel_sheet_title
, table_settings type zexcel_s_table_settings
.
table_settings-table_style = zcl_excel_table=>builtinstyle_medium2.
table_settings-show_row_stripes
= abap_true.
table_settings-nofilters = abap_true.
table_settings-top_left_column
= first_column.
table_settings-top_left_row = 01.
if excel is not bound.
create object excel.
worksheet = excel->get_active_worksheet( ).
else.
worksheet = excel->add_new_worksheet( ).
endif.
worksheet_title = source_description.
worksheet->set_title( worksheet_title ).
worksheet->bind_table(
ip_table = source_stack
is_table_settings = table_settings
).
endmethod.
method send_excel_via_email.
constants : excel_file_type
type string value '.xlsx'
, file_name_parameter
type string value '&SO_FILENAME='
.
data : excel_writer type ref to zif_excel_writer
, excel_as_xstring
type xstring
, excel_as_xstring_bytecount
type i
, excel_as_solix_stack
type solix_tab
, mail_send_request
type ref to cl_bcs
, mail_message type ref to cl_document_bcs
, any_bcs_exception
type ref to cx_bcs
, diagnostic type string
, mail_title type so_obj_des
, mail_text_stack
type soli_tab
, mail_text_entry
like line
of mail_text_stack
, mail_attachment_subject
type sood-objdes
, mail_attachment_bytecount
type sood-objlen
, mail_attachment_header_stack
type soli_tab
, mail_attachment_header_entry
like line of mail_attachment_header_stack
, internet_email_recipient
type ref to if_recipient_bcs
, successful_send
type abap_bool
, file_name type string
.
" Much of the code here was lifted from method send_mail of
" class lcl_ouput, defined in object ZDEMO_EXCEL_OUTPUTOPT_INCL:
concatenate sy-repid " this report name
sy-datum " current date
sy-uzeit " current time
excel_file_type " excel file extension
into file_name.
mail_title = file_name.
mail_attachment_subject = file_name.
mail_text_entry = 'See attachment'.
append mail_text_entry
to mail_text_stack.
concatenate file_name_parameter
file_name
into mail_attachment_header_entry.
append mail_attachment_header_entry
to mail_attachment_header_stack.
create object excel_writer type zcl_excel_writer_2007.
excel_as_xstring = excel_writer->write_file( excel ).
excel_as_solix_stack = cl_bcs_convert=>xstring_to_solix( iv_xstring = excel_as_xstring ).
excel_as_xstring_bytecount = xstrlen( excel_as_xstring ).
mail_attachment_bytecount = excel_as_xstring_bytecount.
try.
mail_message = cl_document_bcs=>create_document(
i_type = 'RAW' "#EC NOTEXT
i_text = mail_text_stack
i_subject = mail_title
).
mail_message->add_attachment(
i_attachment_type = 'XLS' "#EC NOTEXT
i_attachment_subject = mail_attachment_subject
i_attachment_size = mail_attachment_bytecount
i_att_content_hex = excel_as_solix_stack
i_attachment_header = mail_attachment_header_stack
).
mail_send_request = cl_bcs=>create_persistent( ).
mail_send_request->set_document( mail_message ).
internet_email_recipient = cl_cam_address_bcs=>create_internet_address( recipient ).
mail_send_request->add_recipient( internet_email_recipient ).
successful_send = mail_send_request->send( ).
commit work.
if successful_send eq abap_false.
message i500(sbcoms) with recipient.
else.
message s022(so).
message 'Document ready to be sent - Check SOST' type 'I'.
endif.
catch cx_bcs into any_bcs_exception.
diagnostic = any_bcs_exception->if_message~get_text( ).
message diagnostic type 'I'.
endtry.
endmethod.
endclass.
class report definition
final.
public section.
methods : present_report
changing
record_stack
type standard table
.
endclass.
class report implementation.
method present_report.
data : alv_report type ref to cl_salv_table
.
try.
call method cl_salv_table=>factory
importing
r_salv_table = alv_report
changing
t_table = record_stack.
catch cx_salv_msg.
return.
endtry.
alv_report->display( ).
endmethod.
endclass.
class process_driver definition
abstract
final.
public section.
class-methods: drive_process
importing
row_count
type data_exchangeable=>row_counter
recipient
type data_exchangeable=>email_recipient
.
endclass.
class process_driver implementation.
method drive_process.
data : report type ref to report
, excel_spreadsheet_manager
type ref to excel_spreadsheet_manager
, flight_stack type flight_records_retriever=>record_list
, carrier_stack type carrier_records_retriever=>record_list
, booking_stack type booking_records_retriever=>record_list
.
create object: report
, excel_spreadsheet_manager
.
call method flight_records_retriever=>retrieve_records
exporting
row_count = row_count
importing
record_stack = flight_stack.
call method carrier_records_retriever=>retrieve_records
exporting
row_count = row_count
importing
record_stack = carrier_stack.
call method booking_records_retriever=>retrieve_records
exporting
row_count = row_count
importing
record_stack = booking_stack.
call method report->present_report changing record_stack = flight_stack.
call method report->present_report changing record_stack = carrier_stack.
call method report->present_report changing record_stack = booking_stack.
try.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = flight_stack
source_description = 'Flights'.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = carrier_stack
source_description = 'Carriers'.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = booking_stack
source_description = 'Bookings'.
catch zcx_excel ##NO_HANDLER.
endtry.
call method excel_spreadsheet_manager->send_excel_via_email exporting recipient = recipient.
endmethod.
endclass.
class email_address_resolver definition
abstract
final.
public section.
class-methods: resolve_email_address
importing
userid
type syuname
exporting
email_address
type data_exchangeable=>email_recipient
.
endclass.
class email_address_resolver implementation.
method resolve_email_address.
select single smtp_addr
into email_address
from adr6 ##WARN_OK
inner join
usr21 on usr21~persnumber eq adr6~persnumber
where usr21~bname eq userid.
endmethod.
endclass.
parameters : rowcount type data_exchangeable=>row_counter.
parameters : recipien type data_exchangeable=>email_recipient.
initialization.
call method email_address_resolver=>resolve_email_address
exporting
userid = sy-uname
importing
email_address = recipien.
start-of-selection.
call method process_driver=>drive_process
exporting
row_count = rowcount
recipient = recipien.
class excel_spreadsheet_manager definition
final.
public section.
methods : copy_table_to_excel_worksheet
importing
source_stack
type standard table
source_description
type string
raising
zcx_excel
, send_excel_via_email
importing
recipient
type data_exchangeable=>email_recipient
.
private section.
data : excel type string.
endclass.
class excel_spreadsheet_manager implementation.
method copy_table_to_excel_worksheet.
data : source_stack_lines type string.
describe table source_stack lines source_stack_lines.
concatenate excel
source_stack_lines
source_description
into excel separated by space.
endmethod.
method send_excel_via_email.
data : message type string.
concatenate excel
'would be sent to'
recipient
into message separated by space.
message message type 'I'.
endmethod.
endclass.
class zcx_excel definition
inheriting from cx_static_check.
endclass.
Rule 5.3: Do Not Use Static Classes
Preferably use objects instead of static classes. If you don’t want to have a multiple instantiation, you can use singletons.
class car definition
abstract
final.
public section.
class-methods: set_color
importing
color
type string
, set_year
importing
year
type string
.
private section.
class-data : color type string
, year type string
.
endclass.
class car implementation.
method set_color.
car=>color = color.
endmethod.
method set_year.
car=>year = year.
endmethod.
endclass.
call method car=>set_color exporting color = ‘silver’.
call method car=>set_year exporting year = ‘2010’.
class car definition
final.
public section.
methods : set_color
importing
color
type string
, set_year
importing
year
type string
.
private section.
data : color type string
, year type string
.
endclass.
class car implementation.
method set_color.
me->color = color.
endmethod.
method set_year.
me->year = year.
endmethod.
endclass.
data : car_01 type ref to car
, car_02 type ref to car
, car_03 type ref to car
.
create object: car_01
, car_02
, car_03
.
call method car_01->set_color exporting color = 'silver'.
call method car_01->set_year exporting year = '2010'.
call method car_02->set_color exporting color = 'maroon'.
call method car_02->set_year exporting year = '2014'.
call method car_03->set_color exporting color = 'green'.
call method car_03->set_year exporting year = '2015'.
class-data : singleton type ref to flight_records_retriever read-only.
class-methods: class_constructor.
method class_constructor.
create object flight_records_retriever=>singleton.
endmethod.
class flight_records_retriever definition
final
create private.
public section.
types : record_list type standard table of sflight.
class-data : singleton type ref to flight_records_retriever read-only.
class-methods: class_constructor.
methods : retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type flight_records_retriever=>record_list
.
endclass.
class flight_records_retriever implementation.
method class_constructor.
create object flight_records_retriever=>singleton.
endmethod.
method retrieve_records.
select *
into table record_stack
from sflight
up to row_count rows.
endmethod.
endclass.
call method flight_records_retriever=>retrieve_records
call method flight_records_retriever=>singleton->retrieve_records
call method flight_records_retriever=>singleton->retrieve_records ...
call method flight_records_retriever=>singleton->retrieve_records ...
report.
interface data_exchangeable.
types : row_counter type n length 02.
types : email_recipient
type adr6-smtp_addr.
endinterface.
class flight_records_retriever definition
final
create private.
public section.
types : record_list type standard table of sflight.
class-data : singleton type ref to flight_records_retriever read-only.
class-methods: class_constructor.
methods : retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type flight_records_retriever=>record_list
.
endclass.
class flight_records_retriever implementation.
method class_constructor.
create object flight_records_retriever=>singleton.
endmethod.
method retrieve_records.
select *
into table record_stack
from sflight
up to row_count rows.
endmethod.
endclass.
class carrier_records_retriever definition
final
create private.
public section.
types : record_list type standard table of scarr.
class-data : singleton type ref to carrier_records_retriever read-only.
class-methods: class_constructor.
methods : retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type carrier_records_retriever=>record_list
.
endclass.
class carrier_records_retriever implementation.
method class_constructor.
create object carrier_records_retriever=>singleton.
endmethod.
method retrieve_records.
select *
into table record_stack
from scarr
up to row_count rows.
endmethod.
endclass.
class booking_records_retriever definition
final
create private.
public section.
types : record_list type standard table of sbook.
class-data : singleton type ref to booking_records_retriever read-only.
class-methods: class_constructor.
methods : retrieve_records
importing
row_count
type data_exchangeable=>row_counter
exporting
record_stack
type booking_records_retriever=>record_list
.
endclass.
class booking_records_retriever implementation.
method class_constructor.
create object booking_records_retriever=>singleton.
endmethod.
method retrieve_records.
select *
into table record_stack
from sbook
up to row_count rows.
endmethod.
endclass.
class excel_spreadsheet_manager definition
final.
public section.
methods : copy_table_to_excel_worksheet
importing
source_stack
type standard table
source_description
type string
raising
zcx_excel
, send_excel_via_email
importing
recipient
type data_exchangeable=>email_recipient
.
private section.
data : excel type ref to zcl_excel.
endclass.
class excel_spreadsheet_manager implementation.
method copy_table_to_excel_worksheet.
constants : first_column type char1 value 'A'
.
data : worksheet type ref to zcl_excel_worksheet
, worksheet_title
type zexcel_sheet_title
, table_settings type zexcel_s_table_settings
.
table_settings-table_style = zcl_excel_table=>builtinstyle_medium2.
table_settings-show_row_stripes
= abap_true.
table_settings-nofilters = abap_true.
table_settings-top_left_column
= first_column.
table_settings-top_left_row = 01.
if excel is not bound.
create object excel.
worksheet = excel->get_active_worksheet( ).
else.
worksheet = excel->add_new_worksheet( ).
endif.
worksheet_title = source_description.
worksheet->set_title( worksheet_title ).
worksheet->bind_table(
ip_table = source_stack
is_table_settings = table_settings
).
endmethod.
method send_excel_via_email.
constants : excel_file_type
type string value '.xlsx'
, file_name_parameter
type string value '&SO_FILENAME='
.
data : excel_writer type ref to zif_excel_writer
, excel_as_xstring
type xstring
, excel_as_xstring_bytecount
type i
, excel_as_solix_stack
type solix_tab
, mail_send_request
type ref to cl_bcs
, mail_message type ref to cl_document_bcs
, any_bcs_exception
type ref to cx_bcs
, diagnostic type string
, mail_title type so_obj_des
, mail_text_stack
type soli_tab
, mail_text_entry
like line
of mail_text_stack
, mail_attachment_subject
type sood-objdes
, mail_attachment_bytecount
type sood-objlen
, mail_attachment_header_stack
type soli_tab
, mail_attachment_header_entry
like line of mail_attachment_header_stack
, internet_email_recipient
type ref to if_recipient_bcs
, successful_send
type abap_bool
, file_name type string
.
" Much of the code here was lifted from method send_mail of
" class lcl_ouput, defined in object ZDEMO_EXCEL_OUTPUTOPT_INCL:
concatenate sy-repid " this report name
sy-datum " current date
sy-uzeit " current time
excel_file_type " excel file extension
into file_name.
mail_title = file_name.
mail_attachment_subject = file_name.
mail_text_entry = 'See attachment'.
append mail_text_entry
to mail_text_stack.
concatenate file_name_parameter
file_name
into mail_attachment_header_entry.
append mail_attachment_header_entry
to mail_attachment_header_stack.
create object excel_writer type zcl_excel_writer_2007.
excel_as_xstring = excel_writer->write_file( excel ).
excel_as_solix_stack = cl_bcs_convert=>xstring_to_solix( iv_xstring = excel_as_xstring ).
excel_as_xstring_bytecount = xstrlen( excel_as_xstring ).
mail_attachment_bytecount = excel_as_xstring_bytecount.
try.
mail_message = cl_document_bcs=>create_document(
i_type = 'RAW' "#EC NOTEXT
i_text = mail_text_stack
i_subject = mail_title
).
mail_message->add_attachment(
i_attachment_type = 'XLS' "#EC NOTEXT
i_attachment_subject = mail_attachment_subject
i_attachment_size = mail_attachment_bytecount
i_att_content_hex = excel_as_solix_stack
i_attachment_header = mail_attachment_header_stack
).
mail_send_request = cl_bcs=>create_persistent( ).
mail_send_request->set_document( mail_message ).
internet_email_recipient = cl_cam_address_bcs=>create_internet_address( recipient ).
mail_send_request->add_recipient( internet_email_recipient ).
successful_send = mail_send_request->send( ).
commit work.
if successful_send eq abap_false.
message i500(sbcoms) with recipient.
else.
message s022(so).
message 'Document ready to be sent - Check SOST' type 'I'.
endif.
catch cx_bcs into any_bcs_exception.
diagnostic = any_bcs_exception->if_message~get_text( ).
message diagnostic type 'I'.
endtry.
endmethod.
endclass.
class report definition
final.
public section.
methods : present_report
changing
record_stack
type standard table
.
endclass.
class report implementation.
method present_report.
data : alv_report type ref to cl_salv_table
.
try.
call method cl_salv_table=>factory
importing
r_salv_table = alv_report
changing
t_table = record_stack.
catch cx_salv_msg.
return.
endtry.
alv_report->display( ).
endmethod.
endclass.
class process_driver definition
final
create private.
public section.
class-data : singleton type ref to process_driver read-only.
class-methods: class_constructor.
methods : drive_process
importing
row_count
type data_exchangeable=>row_counter
recipient
type data_exchangeable=>email_recipient
.
endclass.
class process_driver implementation.
method class_constructor.
create object process_driver=>singleton.
endmethod.
method drive_process.
data : report type ref to report
, excel_spreadsheet_manager
type ref to excel_spreadsheet_manager
, flight_stack type flight_records_retriever=>record_list
, carrier_stack type carrier_records_retriever=>record_list
, booking_stack type booking_records_retriever=>record_list
.
create object: report
, excel_spreadsheet_manager
.
call method flight_records_retriever=>singleton->retrieve_records
exporting
row_count = row_count
importing
record_stack = flight_stack.
call method carrier_records_retriever=>singleton->retrieve_records
exporting
row_count = row_count
importing
record_stack = carrier_stack.
call method booking_records_retriever=>singleton->retrieve_records
exporting
row_count = row_count
importing
record_stack = booking_stack.
call method report->present_report changing record_stack = flight_stack.
call method report->present_report changing record_stack = carrier_stack.
call method report->present_report changing record_stack = booking_stack.
try.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = flight_stack
source_description = 'Flights'.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = carrier_stack
source_description = 'Carriers'.
call method excel_spreadsheet_manager->copy_table_to_excel_worksheet
exporting
source_stack = booking_stack
source_description = 'Bookings'.
catch zcx_excel ##NO_HANDLER.
endtry.
call method excel_spreadsheet_manager->send_excel_via_email exporting recipient = recipient.
endmethod.
endclass.
class email_address_resolver definition
final
create private.
public section.
class-data : singleton type ref to email_address_resolver read-only.
class-methods: class_constructor.
methods : resolve_email_address
importing
userid
type syuname
exporting
email_address
type data_exchangeable=>email_recipient
.
endclass.
class email_address_resolver implementation.
method class_constructor.
create object email_address_resolver=>singleton.
endmethod.
method resolve_email_address.
select single smtp_addr
into email_address
from adr6 ##WARN_OK
inner join
usr21 on usr21~persnumber eq adr6~persnumber
where usr21~bname eq userid.
endmethod.
endclass.
parameters : rowcount type data_exchangeable=>row_counter.
parameters : recipien type data_exchangeable=>email_recipient.
initialization.
call method email_address_resolver=>singleton->resolve_email_address
exporting
userid = sy-uname
importing
email_address = recipien.
start-of-selection.
call method process_driver=>singleton->drive_process
exporting
row_count = rowcount
recipient = recipien.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |