技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

opensource COBOL:コントロールブレイクサンプル

コントロールブレイク(キー項目が変わる度に何らかの処理を実行)のロジックについて、以前の記事で紹介しました。

https://akira2kun.hatenablog.com/entry/2018/10/06/150330
 
COBOLでサンプルプログラムを作成しましたので、参考までに紹介します。
 
【サンプルプログラム】
       IDENTIFICATION    DIVISION.
       PROGRAM-ID.       CONTBREK.
       ENVIRONMENT       DIVISION.
       INPUT-OUTPUT      SECTION.
       FILE-CONTROL.   
           SELECT  F1  ASSIGN  TO  "C:\tmp\a.txt".
           SELECT  F2  ASSIGN  TO  "C:\tmp\b.txt".
      *
       DATA                  DIVISION.
       FILE                  SECTION.
       FD  F1.
       01  F1R.
           03  F1-REC        PIC X(33).
       FD  F2.
       01  F2R.
           03  F2-REC        PIC X(33).
      *
       WORKING-STORAGE       SECTION.
       01  WORK.
           03  F1-END        PIC X(01).
           03  F1-OLD-KEY    PIC X(07).
       01  F1-REC-WORK.
           03  F1-SYOHIN-CODE
                             PIC X(07).
           03  F1-COMMA1     PIC X(01).
           03  F1-HANBAI-YMD PIC X(08).
           03  F1-COMMA2     PIC X(01).
           03  F1-HANBAI-KOSUU
                             PIC X(05).
           03  F1-COMMA3     PIC X(01).
           03  F1-HANBAI-KINGAKU
                             PIC X(09).
           03  F1-CRLF       PIC X(02).
       01  F2-TITLE-WORK.
           03  F2-ASTER1     PIC X(02) VALUE '**'.
           03  F2-SYOHIN-CODE-TITLE
                             PIC X(07).
           03  F2-ASTER2     PIC X(22)
               VALUE '**********************'.
           03  F2-CRLF-TITLE PIC X(02) VALUE X'0D0A'.
       01  F2-REC-WORK.
           03  F2-SYOHIN-CODE
                             PIC X(07).
           03  F2-COMMA1     PIC X(01).
           03  F2-HANBAI-YMD PIC X(08).
           03  F2-COMMA2     PIC X(01).
           03  F2-HANBAI-KOSUU
                             PIC X(05).
           03  F2-COMMA3     PIC X(01).
           03  F2-HANBAI-KINGAKU
                             PIC X(09).
           03  F2-CRLF       PIC X(02).
      *
       PROCEDURE         DIVISION.
      *
      * 各種処理の呼び出し
      *
       000-CONTROLLER-S.
           PERFORM  100-START-S THRU 100-START-E.
           PERFORM  200-MAIN-S  THRU 200-MAIN-E
               UNTIL F1-END = HIGH-VALUE.
           PERFORM  300-END-S   THRU 300-END-E.
           STOP RUN.
       000-CONTROLLER-E.
      *
      * 前処理
      *
       100-START-S.
           INITIALIZE WORK.
           OPEN  INPUT  F1.
           OPEN  OUTPUT F2.
           PERFORM 210-READ-S THRU 210-READ-E.
       100-START-E.
      *
      * 主処理
      *
       200-MAIN-S.
           IF F1-SYOHIN-CODE NOT = F1-OLD-KEY
               PERFORM 220-WRITE-TITLE-S  THRU 220-WRITE-TITLE-E
               MOVE    F1-SYOHIN-CODE     TO   F1-OLD-KEY
           END-IF.
           PERFORM     230-WRITE-RECORD-S THRU 230-WRITE-RECORD-E.
           PERFORM     210-READ-S         THRU 210-READ-E.
       200-MAIN-E.
      *
      * READ処理
      *
       210-READ-S.
           READ F1
           AT END
               MOVE HIGH-VALUE TO F1-END
               GO TO 210-READ-E
           END-READ.
           MOVE F1-REC         TO F1-REC-WORK.
       210-READ-E.
      *
      * WRITE処理(タイトル)
      *
       220-WRITE-TITLE-S.
           MOVE  F1-SYOHIN-CODE TO F2-SYOHIN-CODE-TITLE.
           MOVE  F2-TITLE-WORK  TO F2-REC.
           WRITE F2R.
       220-WRITE-TITLE-E.
      *
      * WRITE処理(レコード)
      *
       230-WRITE-RECORD-S.
           MOVE  F1-REC-WORK TO F2-REC-WORK.
           MOVE  F2-REC-WORK TO F2-REC.
           WRITE F2R.
       230-WRITE-RECORD-E.
      *
      * 後処理
      *
       300-END-S.
           CLOSE  F1.
           CLOSE  F2.
       300-END-E.
 
【入力ファイル】
・C:\tmp\a.txt
0000001,20180401,00100,00010000
0000001,20180402,00200,00020000
0000002,20180401,00001,00001000
0000003,20180402,00002,00002000
 
【出力ファイル】
・C:\tmp\b.txt
**0000001**********************
0000001,20180401,00100,00010000
0000001,20180402,00200,00020000
**0000002**********************
0000002,20180401,00001,00001000
**0000003**********************
0000003,20180402,00002,00002000

Apache Spark のjavaでの実装についてちょっと調べてみた

Apache Spark 向けのコーディングをjavaで行う機会がありそうなので、空き時間にちょっと調べてみました。
 
・そもそもApache Sparkとは
分散処理用のフレームワークであり、簡潔なコードで分散処理の実装が可能になる。
複数のコンピュータで分散処理を行うことで、大量データを高速で処理することが可能になる。
分散処理用のフレームワークとしてはHadoopもあるが、Apache SparkはHadoopの弱点も解消している。
 
Apache Sparkとは何か――使い方や基礎知識を徹底解説 (1/3)

http://www.atmarkit.co.jp/ait/articles/1608/24/news014.html
 
Apache Sparkのコーディング概要(RDDクラスとは)
コーディングではRDDクラスを使用して大規模データセットを操作する。
RDDクラスには、データセットの値を変換する変換メソッドと、データセットの計算を行うアクションメソッドが存在する。
RDDクラスの戻り値となるデータセットには、Int型やString型、自分で定義したクラス型等を指定できる。
同じ計算についてはキャッシュで返すことも可能。
 
Apache Sparkとは何か――使い方や基礎知識を徹底解説 (3/3)

http://www.atmarkit.co.jp/ait/articles/1608/24/news014_3.html
 
・JavaRDDの生成方法とできること
JavaRDDは、外部データセット(ファイル)を読み込むか、コレクション型をparallelizeメソッドで読み込むことで生成できる。
JavaRDDの変換メソッドでは、条件を満たすレコードのみの抽出や文字列置換・挿入、重複排除等が可能である。
JavaRDDのアクションメソッドでは、RDD全体、要素数、最小値・最大値、先頭の要素値等を返すことができる。
キャッシングはpersistメソッドを使用することで可能。
 
SparkのRDDについて - TASK NOTES

https://www.task-notes.com/entry/20160112/1452525344
 
・タプル型の取り扱い(JavaPairRDD)
タプル型とは、メソッドから二つ以上のオブジェクトを返す時に使う型である。
Apache Sparkではタプル型を取り扱えるが、、scala.Table2等のクラスをimportした上で、JavaPairRDDクラスへの変換が必要である。
 
SparkのPairRDDについて

https://www.task-notes.com/entry/20160131/1454214972
 
・サンプルコード
(JavaRDDを使用する例)
Apache Spark で分散処理入門

https://qiita.com/Hiroki11x/items/4f5129094da4c91955bc
 
(JavaPairRDDを使用する例。文章中の単語数を数え上げるサンプルプログラム。)
Spark入門 _ Hadoop Advent Calendar 2016 #15 | DevelopersIO.html

https://dev.classmethod.jp/hadoop/hadoop-advent-calendar-15-introduction-spark/

コントロールブレイクのロジックの説明

今回は、バッチプログラムで使われるロジックの一つである「コントロールブレイク」について説明します。
「コントロールブレイク」とは特にCOBOLではよく目にするロジックであり、キー項目(「商品番号」「顧客番号」「カード番号」等)順にソートされたデータに対して、キー項目が変わる度にタイトル出力や改ページ等を行うロジックです。
トランザクションファイルトランザクションテーブル(履歴ファイル・履歴テーブル)を読み込み、帳票やハガキ等を出力する時に使われることが多いです。
 
フローチャートと例は以下の通りです。
 
フローチャート

f:id:akira2kun:20181006150241j:plain

 
【例】
・要件
商品の販売実績のデータをまとめたファイルを読み込み、商品毎にタイトルを付与して、別のファイルに出力したい。
 
・入力ファイルのフォーマット
カンマ区切りの固定長ファイル。
商品コード・販売日でレコードを一意に特定できるようにデータをセットする。
 
商品コード(7桁)
カンマ(1桁)
販売日(8桁)
カンマ(1桁)
販売個数(5桁)
カンマ(1桁)
販売金額(9桁)
 
・入力ファイルのレコード
0000001,20180401,00100,00010000
0000001,20180402,00200,00020000
0000002,20180401,00001,00001000
0000003,20180402,00002,00002000
 
・タイトル行のフォーマット
アスタリスク(2桁)
商品コード(7桁)
アスタリスク(22桁)
 
・処理の流れ
 ①変数「旧キー」に初期値として7桁のスペースを入れる。
  (商品コードで使われていない値を初期値として使用する)
 ②1レコード目「0000001,20180401,00100,00010000」を読み込む。
 ③読み込んだレコードの商品コードと変数「旧キー」が一致するか判定する。
  一致しないため、ブレイク処理として下記タイトルを出力する。
  「**0000001**********************」
  変数「旧キー」に現在の商品コード「0000001」をセットする。
 ④1レコード目のデータを出力ファイルへ出力する。
 ⑤2レコード目「0000001,20180402,00200,00020000」を読み込む。
 ⑥読み込んだレコードの商品コードと変数「旧キー」が一致するか判定する。
  一致するため、ブレイク処理は行わない。
 ⑦2レコード目のデータを出力ファイルへ出力する。
 ⑧3レコード目「0000002,20180401,00001,00001000」を読み込む。
 ⑨読み込んだレコードの商品コードと変数「旧キー」が一致するか判定する。
  一致しないため、ブレイク処理として下記タイトルを出力する。
  「**0000002**********************」
  変数「旧キー」に現在の商品コード「0000002」をセットする。
 ⑩3レコード目のデータを出力ファイルへ出力する。
 ⑪4レコード目「0000003,20180402,00002,00002000」を読み込む。
 ⑫読み込んだレコードの商品コードと変数「旧キー」が一致するか判定する。
  一致しないため、ブレイク処理として下記タイトルを出力する。
  「**0000003**********************」
  変数「旧キー」に現在の商品コード「0000003」をセットする。
 ⑬4レコード目のデータを出力ファイルへ出力する。
 ⑭EOFのため処理を終了する。
 
・出力ファイル
**0000001**********************
0000001,20180401,00100,00010000
0000001,20180402,00200,00020000
**0000002**********************
0000002,20180401,00001,00001000
**0000003**********************
0000003,20180402,00002,00002000

COBOLにおけるパック10進数(COMP-3)のデータの持ち方

パック10進数は色々なサイトで説明されていますが、今回の記事では正確さは置いといて実務で必要な知識をわかりやすく説明します。
 
【パック10進数とは】
パック10進数は、1バイトで数値2桁を表現する形式です。
バイト数を削減できる、16進で文字コードを見た時に見やすい、という利点があります。
 
COBOLでは、ワークの定義時に「COMP-3」をつけることでパック10進数形式になります。
 
・通常の定義の場合
03  NUM   PIC S9(3).
 
・パック10進数で定義する場合
03  NUM   PIC S9(3) COMP-3.
 
※「9」は数値タイプ。また「S」を定義すると符号を扱えるようになる。
 
【16進数にした場合の文字の見え方】
1バイトの文字を16進数で表現すると"00"(LOW-VALUE)~"FF"(HIGH-VALUE)になります。
1バイトにつき0~Fの範囲の文字が2つくっついたような形になります。
 
「PIC 9(3)」で定義したワークに「123」を代入すると、16進数では以下のように見えます。
文字コードEBCDICの場合)
F1 F2 F3
EBCDICの場合、「1」は16進数で「F1」、「2」は「F2」、「3」は「F3」なので、こうなります。
 
それに対して、「PIC 9(3) COMP-3」でワークが定義されていると以下のようになります。
12 3C
この例を見れば、「1バイトで数値2桁を表現する」というのが直感的に理解できると思います。
 
ちなみに、COMP-3のワークの一番後ろの「C」は、プラスを表しています。
マイナスの値の場合はこれが「D」になります。
つまり、「PIC S9(3) COMP-3」で定義したワークに「-123」を代入するとこうなります。
12 3D
 
【パック10進数のワークのバイト数】
結論から言うと以下です。
 (数値の桁数/2)+0.5 ※小数点以下切り上げ
 
「数値の桁数/2」は「1バイトで数値2桁を表現する」を表しています。
「+0.5」は後ろに付与される符号(C/D)を表しており、これが0.5バイトに相当します。
 
「小数点以下切り上げ」は、1バイトに満たない文字が現れた場合のゼロ埋めを示しています。
例えば、「PIC 9(4) COMP-3」で定義したワークに「1234」を代入すると以下になります。
01 23 4C
前に「0」を入れないと1バイトに満たない箇所が現れてしまうので、前に「0」を入れて1バイト単位にしています。
 
【パック10進数を扱う時の注意点】
9タイプはXタイプ(文字タイプ)と16進数にした時の表現が同じなので、9タイプからXタイプへのMOVEは上手く行きます。
しかし、9 COMP-3タイプとXタイプは表現が異なるので、9 COMP-3タイプからXタイプへMOVEすると文字化けしたり異常終了したりする原因になります。
なお、9 COMP-3タイプから9タイプへのMOVEは自動的に変換されるので問題ありません。
 
【正確な情報が知りたい場合】
以上の説明はわかりやすさ重視の説明なので、正確な情報が知りたい場合はWikipedia等を見た方が良いです。
 
パック10進数 - Wikipedia

https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%83%E3%82%AF10%E9%80%B2%E6%95%B0
 
なお、最近は出題がないようなのですが、かつては情報処理技術者試験でも出題されるテーマでした。
時代の流れ的に出題頻度は低くなるはずですが、忘れた頃に出題される可能性もあるので、念のためリンクを貼っておきます。
 
パック10進数 [徹底研究!情報処理試験]

http://mt-net.vis.ne.jp/ADFE_mail/0333.htm

---------------------
情報処理技術者試験対策 目次

https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

opensource COBOL:ファイル入出力サンプル

opensourceCOBOL(Windows版)の挙動把握のため、ファイル入出力のサンプルを作成しました。
ファイルを4バイトずつ読み込んで、改行コードを付けて別のファイルに出力するサンプルです。
 
これができるということは、実務に近いプログラムも作れるはずです。
ソースコードHELLO WORLDと比べると大分COBOLっぽくなってます。
 
ソースコード
       IDENTIFICATION    DIVISION.
       PROGRAM-ID.       FILINOUT.
       ENVIRONMENT       DIVISION.
       INPUT-OUTPUT      SECTION.
       FILE-CONTROL.   
           SELECT  F1  ASSIGN  TO  "C:\tmp\a.txt".
           SELECT  F2  ASSIGN  TO  "C:\tmp\b.txt".
      *
       DATA                  DIVISION.
       FILE                  SECTION.
       FD  F1.
       01  F1R.
           03  F1-REC        PIC X(04).
       FD  F2.
       01  F2R.
           03  F2-REC        PIC X(06).
      *
       WORKING-STORAGE       SECTION.
       01  WORK.
           03  F1-END        PIC X(01).
       01  F2-REC-WORK.
           03  F2-STR        PIC X(04).
           03  KAIGYO        PIC X(02) VALUE X"0D0A".
      *
       PROCEDURE         DIVISION.
      *
      * 各種処理の呼び出し
      *
       000-CONTROLLER-S.
           PERFORM  100-START-S THRU 100-START-E.
           PERFORM  200-MAIN-S  THRU 200-MAIN-E
               UNTIL F1-END = HIGH-VALUE.
           PERFORM  300-END-S   THRU 300-END-E.
           STOP RUN.
       000-CONTROLLER-E.
      *
      * 前処理
      *
       100-START-S.
           INITIALIZE WORK.
           OPEN  INPUT  F1.
           OPEN  OUTPUT F2.
           PERFORM 210-READ-S THRU 210-READ-E.
       100-START-E.
      *
      * 主処理
      *
       200-MAIN-S.
           MOVE F1-REC      TO F2-STR.
           MOVE F2-REC-WORK TO F2-REC.
           WRITE F2R.
           PERFORM 210-READ-S THRU 210-READ-E.
       200-MAIN-E.
      *
      * READ処理
      *
       210-READ-S.
           READ F1
           AT END
               MOVE HIGH-VALUE TO F1-END
           END-READ.
       210-READ-E.
      *
      * 後処理
      *
       300-END-S.
           CLOSE  F1.
           CLOSE  F2.
       300-END-E.
 
【テストデータ】
・C:\tmp\a.txt
HOGEFUGAPIYO
 
【出力結果】
・C:\tmp\b.txt
HOGE
FUGA
PIYO

本番作業をミスなく行うために必要なこと(一般論)

IT業界では、プログラムのリリースや運用作業、緊急対応等で、本番環境で作業を行うことが良くあります。
本番環境での作業は、一つのミスがユーザに影響を与えることになりかねないので、作業ミスがしばしば問題になります。
 
今回は、本番環境での作業をミスなく行うために必要な準備・体制について、一般論を簡単に書きます。
当たり前と言えば当たり前のことなのですが、ミッションクリティカルなシステムに携わったことがない人はこういったものを学ぶ機会がないので。
 
下記は一般論であり、緊急対応等で時間がない場合は十分な準備ができない場合もありますが、それでもできる限りあるべき姿に近づけようとすることが重要です。
 
【本番作業にあたり必要な準備・体制】
1.手順書の作成
 本番作業を行うにあたり、手順書を作成する。
 手順書には以下の内容を盛り込む。
  ・作業の目的を明確に書く
  ・作業時の体制を明確に書く
   (誰がどのような立場で関わるのか)
  ・タイムチャートを作成し、作業のタイミングを明確にする
   (作業間に前後関係があるならそれも表現する)
  ・作業内容は徐々にブレークダウンし、最終的にはコマンドに落とし込む
   (手順書を見れば誰でも作業できるようにする)
  ・各々の作業についてチェックボックスをつける
   (完了した作業にレ点を入れて作業漏れを防げるようにする)
  ・可能であれば作業は自動化する
   (人力での作業はスピードが遅く、作業ミスの危険もある)
 
2.手順書のレビュー
 作成した手順書について、有識者のレビューを受ける。
 指摘があればそれを手順書に反映させる。
 
3.手順書の承認
 完成した手順書を上長に説明し、作業の許可を得る。
 (上長は、どのような本番作業が予定され、どのようなリスクがあるのか把握する)
 
4.本番作業の実施
 本番作業は以下のように実施する。
  ・手順書の通りに作業する。完了した作業にはレ点をつけ、作業漏れを防ぐ。
  ・二人以上の目でダブルチェックを行う。危険な作業では指差し確認も行う。
  ・手順書外の作業が必要になった場合は、その場でレビューし上長の許可を得る。
   (作業者の独断で勝手な作業をしてはならない)
 
5.作業の完了報告
 作業結果を上長に報告する。
 (予定通りに終わったのか。予定通りでない場合はどこが予定通りでないのか。)
 
6.作業の振り返り
 本番作業を行う中で手順の改善点が見つかれば、それを次回の手順書に反映する。

Gofのデザインパターンの自分なりのまとめ

増補改訂版Java言語で学ぶデザインパターン入門」という本でGofデザインパターンを勉強しました。
自分の知識の整理も兼ねて、どのようなデザインパターンが存在し、どのような場合に適用できるのかを簡単にまとめたいと思います。
 
なお、この本とほぼ同様のことが以下のページで紹介されています。
 
デザインパターン  TECHSCORE(テックスコア)

http://www.techscore.com/tech/DesignPattern/index.html/
 
00.デザインパターン 概論
 ・デザインパターンとは何か
  オブジェクト指向言語における設計のパターン集。
  良く出会う問題とその解決法となる設計を名前をつけてまとめたもの。
  
 ・デザインパターンを用いるメリットとは何か
  変更に対する影響箇所が少なくなる設計を行う上でのヒントとなる。
  また、開発者間でのコミュニケーションがスムーズになる。
  (「このクラスを作って、クラス間の…」が「○○パターンにしよう」になる)
  
01.Iterator パターン
 ・何を意図した設計なのか
  複数の要素を順番に取り出すためのクラスを作成する。
  (Javaで標準で用意されているIteratorもこのパターンを利用している)
  
 ・どのような場合に有効なのか
  複数の要素に対して決められた順番で処理する必要がある場合。
  
02.Adapter パターン
 ・何を意図した設計なのか
  他システムのインターフェースと自システムの架け橋となるクラスを作成する。
  (アダプタのように変換を行う)
  
 ・どのような場合に有効なのか
  他システムのインターフェースに合わせる必要がある場合。
  
03.TemplateMethod パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  (抽象クラスがテンプレートとなる)
  
 ・どのような場合に有効なのか
  似たような処理をいくつも実装する場合。
  
04.FactoryMethod パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  オブジェクトを生成するクラスとそのオブジェクトを使用するクラスに分ける。
  (オブジェクトを生成するクラスはFactoryと呼ばれる)
  
 ・どのような場合に有効なのか
  利用するオブジェクトに頻繁に変更が入る場合。
  複数のオブジェクトを利用する場合。
  
05.Singleton パターン
 ・何を意図した設計なのか
  インスタンスが絶対に一個しか作成されないようなクラスを作成する。
  
 ・どのような場合に有効なのか
  インスタンスが複数存在すると制御が困難になるクラスを作成する場合。
  
06.Prototype パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  処理を利用するクラスには抽象クラスを使わせる。
  インスタンスを作成する場合は既存のインスタンスをコピーする。
  (既存のインスタンスがプロトタイプとなる)
  
 ・どのような場合に有効なのか
  処理の種類が多く一つのクラスにまとめられない場合。
  複雑な処理過程があり、クラスからインスタンスを一から生成するのが難しい場合。
  インスタンス生成のフレームワークで具体的なクラス名を指定したくない場合。
  
07.Builder パターン
 ・何を意図した設計なのか
  処理の概要を抽象クラス、具体的な処理内容を具象クラスに記述する。
  処理を利用するクラスには抽象クラスを使わせる。
  抽象クラスのメソッドを利用し、組み上げることで、複雑なものを作成する。
  
 ・どのような場合に有効なのか
  大きな構造を持ったものを段階的に組み上げたい場合。
  
08.AbstractFactory パターン
 ・何を意図した設計なのか
  大きな構造を持ったものを作るのに必要な部品をクラスとして定義する。
  部品を表すクラスのオブジェクトを生成するクラスも作成する。
  これらのクラスを抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  抽象クラス(API)を柔軟に組み合わせて大きな構造を組み立てたい場合。
  
09.Bridge パターン
 ・何を意図した設計なのか
  機能を実装するクラスと、機能を利用するクラスに分ける。
  機能を利用するクラスは、実際の処理を機能を実装するクラスに委譲する。

  (橋渡し)
  これらのクラスは抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  頻繁な機能追加が予想される場合。
  
10.Strategy パターン
 ・何を意図した設計なのか
  問題を処理するロジック(戦略)について、抽象クラスと具象クラスに分ける。
  ロジックを使って問題を解くクラスには抽象クラスを使わせる。
  
 ・どのような場合に有効なのか
  問題を処理するロジックが複数通り存在する場合。
  
11.Composite パターン
 ・何を意図した設計なのか
  葉となるクラスと、葉や容器を格納する容器となるクラスを作成する。
  これらのクラスについて抽象クラスを作成する。
  
 ・どのような場合に有効なのか
  ディレクトリ構造のように入れ子になっている場合。
  
12.Decorator パターン
 ・何を意図した設計なのか
  葉となるクラスと、葉や容器を格納する容器となるクラスを作成する。
  容器となるクラスには、葉となるクラスを飾りつける処理を含める。
  (容器となるクラスは、抽象クラスと具象クラスに分ける)
  葉となるクラスと容器となるクラスの抽象クラスも作成する。
  
 ・どのような場合に有効なのか
  ある要素を飾り付けるための処理を複数実装したい場合。
  (文字列に対して、別の文字列をどんどん付け加えていく等)
  
13.Visitor パターン
 ・何を意図した設計なのか
  Compositeパターン等で作成したデータ構造に対して処理を行うクラスを実装する。
  (データ構造に対して処理を行うクラスがVisitorに相当する)
  
 ・どのような場合に有効なのか
  あるデータ構造に対して処理を行う場合。
  
14.ChainOfResponsibility パターン
 ・何を意図した設計なのか
  問題を処理するロジックについて、抽象クラスと具象クラスに分ける。
  抽象クラスは自らのクラスへの委譲を行う。
  これで、ある具象クラスで解決できない場合に他の具象クラスを使うことができる。
  (責任のたらい回し)
  
 ・どのような場合に有効なのか
  問題を処理するロジックに独立性を持たせたい場合。
  (問題が解決できなかった場合の処理まで持たせたくない場合)
  
15.Facade パターン
 ・何を意図した設計なのか
  複数のクラスを適切な順番で組み合わせる窓口クラスを作成する。
  機能を利用するクラスには窓口クラスを利用させる。
  
 ・どのような場合に有効なのか
  機能を利用する側に複雑な処理を見せたくない場合。
  
16.Mediator パターン
 ・何を意図した設計なのか
  具体的な処理を行う複数のクラスと、それらのクラスの抽象クラスを作成する。
  また、それらのクラスの調停を行うクラスも作成する。
  調停クラスも抽象クラスと具象クラスに分ける。
  
 ・どのような場合に有効なのか
  具体的な処理を行う複数のクラスの処理が複雑に絡み合う場合。
  (例:チェックボックスで○○が選択されたらメッセージボックスを不活性化)
  
17.Observer パターン
 ・何を意図した設計なのか
  状態を観察するクラスと、状態の変化に合わせて処理を行うクラスに分ける。
  観察するクラスは状態の変化の検知後、処理を行うクラスのメソッドを実行する。
  
 ・どのような場合に有効なのか
  状態の変化に合わせて処理を行う必要がある場合。
  
18.Memento パターン
 ・何を意図した設計なのか
  状態を保存するクラスを作成する。
  (ゲームで言うセーブデータ(記録)をクラスとして用意する)
  
 ・どのような場合に有効なのか
  状態を保存して、その状態に戻れるようにしたい場合。
  
19.State パターン
 ・何を意図した設計なのか
  「昼間」「夜間」等の状態について、それらの状態毎にクラスを作成する。
  (状態を表すクラスの抽象クラスも作成する)
  
 ・どのような場合に有効なのか
  状態が多く、状態に応じて複雑なロジック実装が必要な場合。
  
20.Flyweight パターン
 ・何を意図した設計なのか
  メモリ等のリソースの無駄を省くことを意図する。
  オブジェクトが生成済みなら再びオブジェクトが生成されないようにする。
  それを実現するためのFactoryクラスを作成する。
  
 ・どのような場合に有効なのか
  一つのオブジェクトを使い回すことでリソース節約が可能な場合。
  
21.Proxy パターン
 ・何を意図した設計なのか
  重い処理を行うクラスが存在する場合に負荷を下げることを意図する。
  極力そのクラスを使わなくても済むようにするため、代理の軽いクラスを作成する。
  これらのクラスは、同一視できるように抽象クラスでまとめる。
  
 ・どのような場合に有効なのか
  思い処理を行うクラスが存在し、そのクラスの代役を作ることが可能な場合。
  
22.Command パターン
 ・何を意図した設計なのか
  複数の命令毎にクラス化し、それらの命令クラスを束ねる抽象クラスも作成する。
  命令を利用するクラスは、その抽象クラスを利用する。
  命令の具象クラスは、対象物を表すクラスに対して処理を行う。
  
 ・どのような場合に有効なのか
  複数の命令が存在し、命令の追加が予想される場合。
  命令を組み合わせて別の命令を作る場合。
  
23.Interpreter パターン
 ・何を意図した設計なのか
  命令を記述するための簡単なミニ言語(設定ファイル)を作る。
  そのミニ言語を解釈するためのクラスをjavaで実装する。
  (例:終端文字を扱うクラスと非終端文字を扱うクラスを作成する)
  
 ・どのような場合に有効なのか
  javaを修正しなくても、ミニ言語を修正するだけで変更を可能としたい場合。