【ABAP】はじめてのデザインパターン
デザインパターンとは
デザインパターンとは、オブジェクト指向で用いられる、クラスの「型」のようなものです。ソフトウェア開発の歴史の中で、クラスを再利用、拡張しやすいように先人たちが考えた設計が体系化されています。
プログラムの開発においては似たような問題を扱うことがよくあり、デザインパターンを適用することで再利用性に優れた設計をすることができます。デザインパターン知っておくことで、既存のコードを読むときに理解が深まったり、設計者、開発者同士で共通認識を持てるというメリットもあります。
デザインパターンを学ぶ
デザインパターンの古典と呼ばれる本にDesign Patterns: Elements of Reusable Object-Oriented Softwareがあります。最初に「先人たちの知恵」をまとめた本です。読んでみたのですが、私にはかなり難解でした。
次に、ABAPのデザインパターンについて書かれたDesign Patterns in ABAP Objectsを読みました。こちらは語り口もわかりやすく、サンプルコードも当然ABAPなので理解しやすかったです。OO ABAPを使っていこうとする人におすすめです。
この本では27のデザインパターンが紹介されていますが、この記事では初めに知っておくとよいと思うデザインパターンを2つ紹介します。
紹介するデザインパターン
Strategy
同じインターフェース(型)を共有する複数のクラスがあり、実行時にどのクラスを使うのかを動的に決定します。各クラスは同じメソッドを持っているので、プログラムからはそれらを区別なく使うことができます。
Factory
Strategyでは、なんらかの条件にもとづいてどのクラスを使用するかを決定します。Factoryは、クラス決定のためのロジックを定義するクラス(またはメソッド)です。Factoryを使えば、プログラム側ではどのクラスを生成するかを意識しなくて済みます。
ユースケース
カスタムワークフローを作るケースを考えてみます。ワークフロープログラムを使って、さまざまな伝票(購買発注、会計伝票など)を承認します。
承認処理は伝票によってさまざまです。例えば購買発注はリリースステータスが設定され、会計伝票は転記がされます。
Strategy
伝票種別ごとの承認処理を個別のクラスに記述します。各クラスは共通のインターフェースを実装しています。
Factory
伝票種別ごとに使用するクラスを決定してオブジェクトを生成します。
Strategyの実装
インターフェースの実装は以下のようになります。
INTERFACE zif_approve
PUBLIC .
METHODS approve
IMPORTING iv_key type string
RETURNING VALUE(rt_return) TYPE bapiret2_t.
ENDINTERFACE.
購買発注承認用のクラスは以下のようになります。簡単にするため承認処理は書いていません。
CLASS zcl_approve_po DEFINITION
PUBLIC
INHERITING FROM zcl_approve_abs
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS zif_approve~approve REDEFINITION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_approve_po IMPLEMENTATION.
METHOD zif_approve~approve.
"承認処理 (BAPI)
WRITE: |PO { iv_key } has been approved.|.
ENDMETHOD.
ENDCLASS.
会計伝票承認用のクラスは以下のようになります。
CLASS zcl_approve_acc_doc DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_approve.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_approve_acc_doc IMPLEMENTATION.
METHOD zif_approve~approve.
"転記処理
WRITE: |Accounting doc { iv_key } has been approved.|.
ENDMETHOD.
ENDCLASS.
メインのプログラムは以下のようになります。
REPORT zsample_wf.
PARAMETERS:
p_type TYPE string DEFAULT 'PO',
p_key TYPE string.
START-OF-SELECTION.
DATA: lo_approve TYPE REF TO zif_approve.
"TODO:承認用のクラスを決定する
"承認処理
lo_approve->approve( p_key ).
Factoryの実装
入力された伝票種別にもとづいて生成するクラスを判断します。
CLASS zcl_approve_factory DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS get_instance
IMPORTING iv_doc_type TYPE string
RETURNING VALUE(ro_approve) TYPE REF TO zif_approve
RAISING cx_class_not_existent.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_approve_factory IMPLEMENTATION.
METHOD get_instance.
CASE iv_doc_type.
WHEN 'PO'.
ro_approve ?= NEW zcl_approve_po( ).
WHEN 'ACC'.
ro_approve ?= NEW zcl_approve_acc_doc( ).
WHEN OTHERS.
RAISE EXCEPTION TYPE cx_class_not_existent.
ENDCASE.
ENDMETHOD.
ENDCLASS.
Factoryクラスを使うと、プログラムの処理は以下のようになります。
"承認用のクラスを決定
TRY.
lo_approve ?= zcl_approve_factory=>get_instance( p_type ).
CATCH cx_class_not_existent.
LEAVE LIST-PROCESSING.
ENDTRY.
"承認処理
lo_approve->approve( p_key ).
動作
伝票種別に「PO」と入力して実行すると、以下のメッセージが表示されます。
伝票種別に「ACC」と入力して実行すると、以下のメッセージが表示されます。
他のデザインパターン
今回のケースでは、簡単にするために伝票のキーは1つだけ、かつString型でした。実際には伝票によってキーの型や数が変わります。そんな時にはProperty Containerのパターンが使えます。Property Containerは、キー + バリュー形式のテーブルと、テーブルへのSet、Getメソッドを持ったクラスです。
また、購買発注承認用クラスと会計伝票承認用クラスで一部のメソッドを共有したい場合もあると思います(たとえば、エラーハンドリングなど)。そんなときは、Template Methodのパターンを使って、抽象クラスに共通メソッドを実装し、そのクラスを継承して個別のクラスを作ることもできます。
Author And Source
この問題について(【ABAP】はじめてのデザインパターン), 我々は、より多くの情報をここで見つけました https://qiita.com/tami/items/0b577839b9ade1dff0fc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .