嘉巳Tweetデザインパターンとは今回のテーマは「デザインパターン」です。デザインパターンとはクラス設計における定石集で、全部で23パターンあり、それぞれに特徴があります。MethodパターンとStateパターンですが、SingletonパターンやCompositeパターンなどもよく利用されます。MethodパターンとStateパターンについて、前回解説した例題とクラス図を使用して解説します。Method)を適用する前回解説した例題を使って、デザインパターンが適用できないかを検討してみましょう。前回の例題とクラス図を再掲します。「A社には社員として鈴木さん、佐藤さん、高橋さんがいます。各クラスがそれぞれ「身支度をする」メソッドを呼び、次に「通勤電車に乗る」メソッドを呼び、最後に「現場で仕事をする」メソッドを呼ぶ作りになっています。各クラスはそれぞれ身支度の仕方や通勤電車の種類、仕事の内容は違いますが(例えば「鈴木」クラスの「身支度をする」メソッドは「洗面所で顔を洗う」、「通勤電車に乗る」メソッドは「京急線を使う」だが、「佐藤」クラスの「身支度をする」メソッドは「シャワーを浴びる」、「通勤電車に乗る」メソッドは「山手線を使う」など)、各メソッドの振る舞い(内容)は違っても「身支度をする」メソッドを呼んで「通勤電車に乗る」メソッドを呼び、最後に「現場で仕事をする」メソッドを呼ぶ、処理の流れ(順番)は一緒です。Methodパターンが適用できそうです。Methodパターンとは、親クラスで処理の流れ(アルゴリズム)を実装し、処理の流れで順次呼ばれるメソッドを抽象メソッド(定義だけでサブクラスに処理を強制的に実装させるためのメソッド)として宣言します。親クラスで宣言した抽象メソッドの具体的な処理はサブクラスで実装します。上のサンプルのように、処理の内容は違っても処理の流れは一緒のような状況はプログラミングで割と起こるかと思います。Methodパターンを適用すると親クラスに処理の流れを記したテンプレートメソッドを用意し、そのテンプレートメソッドからは次々にメソッドが呼ばれていくため(テンプレートメソッドから呼ばれるメソッドをフックメソッドという)、サブクラスはフックメソッドをオーバーライド実装するだけとなります。オーバーライドとは、親クラスで定義しているメソッドをサブクラスで再定義(上書き)することを言います。親クラスで定義しているメソッドの振る舞いをサブクラスでは異なる振る舞いにしたい場合に使用します。親クラスで定義しているメソッドが抽象メソッドの場合は、強制的にサブクラスでオーバライド実装することになります。Methodパターンを適用すると、サブクラスはメソッドを順番に呼ぶ必要はありません。順番に呼ぶ責務は親クラスになります。親クラスである社員クラスのプログラムを以下に書きます。現場で仕事をする();}一日の行動()メソッドがテンプレートメソッドです。テンプレートの文字通り、処理の流れのひな型を定義するので、サブクラスは処理の流れを考える必要はなく、メソッドの振る舞いを実装するだけになりました。}}Stateパターンを適用する次に、例題に以下の文章を追加します。「このうち鈴木さんはフェーズによって仕事の内容が変わります。何も考えないとクラス図はそのままで、鈴木クラスの「現場で仕事をする」メソッドにif文でフェーズを分岐するプログラムを作ることを考えるでしょう。}}これでも要件を満たして動作しますが、if文を使うとフェーズの条件が増えた場合に、if文の分岐も増やさないといけません。プログラムに手を入れるということは、そのクラスを再テストしなくてはいけなくなるため、非常に効率が悪いです。効率が悪いだけならまだしも、正しく動いているものを修正することでバグを生み出してしまうなど、if文の分岐は数が多いと可読性が低下します。そこで、第2回で解説したJavaのようなオブジェクト指向言語の最大の特徴とも言える「ポリモーフィズム」を使わない手はありません。追加された例題をもう一度よく読んでみます。「鈴木さんはフェーズによって仕事の内容が変わります。設計フェーズでは......」となっています。冒頭で幾つかよく使用されるデザインパターンを挙げましたが、このケースではその中で状態によって振る舞いが変わる場合はStateパターンが適用できそうです。Stateパターンとは、文字通りモノについての「状態」をクラスで表現します。状態によって振る舞い(処理)が異なることがあります。挨拶は時間帯によって変わります。朝であれば「おはよう」ですが、昼は「こんにちは」になり、夜は「こんばんは」になります。挨拶は「おはよう」で固定されているわけではなく、状態(この場合は時間帯が状態といえます)によって振る舞いが異なります。このような場合にStateパターンを適用すると個々のクラスで状態を表現するため、分岐が消えてシンプルな作りになります。ちなみに、状態によって振る舞いが変わる場合はStateパターンですが、この「状態によって振る舞いが変わる」が例題の「フェーズによって仕事の内容が変わる」に当てはまり、Stateパターンの「状態」が例題の「フェーズ」に当てはまるわけです。それでは試してみましょう。例題ではフェーズの状態によって仕事の内容が変わるので、仕事内容の変化はif文ではなく「フェーズ」というインターフェースを用意します。フェーズインターフェースには「仕事をする」宣言を定義し、交換可能な作りにします。仕事をする();}フェーズインターフェースを実装したクラスは、状態(フェーズ)ごとの具体的な振る舞い(仕事内容)を記述します。}}鈴木クラスの「現場で仕事をする」メソッドは、次のようになります。}}仕事内容の変化はif文ではなく、受け取ったインスタンスによって異なる振る舞いをする、まさにポリモーフィズムで変えています。クラス図で表すと下図のようになります。鈴木クラスからフェーズインターフェースには菱形のない実線だけで線を引いていますが、前回解説した包含は菱形の付いている実線で表します。包含は集約とも言い、「全体と部分」の意味を持つ場合に用いため、今回の「鈴木」と「フェーズ」は関係があるという意味の「関連」にします。関連は実線だけで表します。「依存」というものもあります。依存は関連よりもクラス間の依存度が低く、協調の長さが短い場合に用います。プログラムで言うとインスタンス変数ではなく、メソッド内で定義するローカル変数で対象のクラスを表します。依存はクラス間の点線で表します。一度、ここまでで期待通りに動作するかテストクラスを作って確認してみましょう。その前に、日本語で書いたクラスを論理モデルから物理モデルに進めて英語に直します。}}テストクラスを作成して、動作するか試してみましょう。}}実行すると、コンソールには期待通り、以下のように表示されました。洗面所で顔を洗う京急線を使う設計書を作成するシャワーを浴びる山手線を使うプログラムを作る朝風呂に入る総武線を使う設計書を作るあとは、鈴木クラスの「現場で仕事をする」メソッドが状態(フェーズ)の違いで異なる振る舞いをしてくれるかですね。}}こちらも実行して、期待通りの結果になるかコンソールを確認してみましょう。洗面所で顔を洗う京急線を使うプログラムを作成する洗面所で顔を洗う京急線を使うテスト計画書を作成する上手いこと「現場で仕事をする」メソッドの振る舞いが変わりましたね。優れたクラス設計にするにはStateパターンによって「鈴木さんはフェーズによって仕事の内容が変わる」という要件は満たしましたが、これは「スナップショット的な考え」でしかありません。スナップショット的な考えとは、「時間的な断面を切り取った状態の考え」、つまり「今回の要件を満たせばOK」という考えです。それではダメで、あくまで全体、このプロジェクトの機能はどうなっていくのだろうと、もっと大局的に見ていかなければなりません。クラス設計にしても、確かに「鈴木はフェーズによって仕事の内容が変わる」という今回の要件は満たしましたが、「仕様変更や次のフェーズでは佐藤クラスや高橋クラスにも同様にフェーズによって仕事の内容が変わるという要望が発生するかもしれない」と察知しないといけません。そのような要望があった時に都度クラスやプログラムを変更していたのでは工数が掛かって仕方がないので、フェーズによって鈴木クラスの仕事内容が切り替わるのなら「今のうちに他のクラスも同様に切り替わる作りにしよう」と考えましょう。したがって、クラス図は最初に挙げた鈴木クラスからフェーズインターフェースに関連を持ったクラス図ではなく、どの社員も仕事内容が切り替わるように、社員クラスからフェーズインターフェースに関連を持つ以下のクラス図の方が優れた設計と言えます。ちなみに、社員が増えた場合は他のプログラムには一切手を付けることなく、抽象クラスである社員クラスを継承したクラスを追加するだけです。フェーズが増えて仕事内容が増えた場合は、フェーズインターフェースを実装したクラスを追加するだけです。こちらも他のプログラムの修正は一切不要です。おわりにいかがでしたか。MethodパターンとStateパターンについて解説しました。次回はオブジェクト指向の設計原則について解説します。サンクJavaを使ったシステム開発に従事し、オブジェクト指向での設計から開発を得意としている。以前はデザインパターンを取り入れたクラス設計やリファクタリングでのコードの体質改善という作業も行っていた。自分の力がまだまだと自覚しており、JavaやUMLの資格も積極的に取得している。仕事の傍らスキー1級やスノボ、テニス、また、野菜ソムリエ取得やフランス料理学校に通うなど、仕事よりも趣味の方に重きを置いているのが玉に瑕。ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。IT会員サービスの概要とメリットをチェック他にもこの記事が読まれています開発ツールイベントGitHub、エンタープライズ向けのイベントを国内で開催。2019でプロダクトデザイナーに訊いた、易しさと高機能をバランスさせるチャレンジ2020/2/10システム開発イベント普段の仕事では得られない、新しい知見や発見がある。キャリアアップにもつながる。VeloCloudが選ばれる理由SD-WANとはなにか。Linuxエンジニア育成への思いF5とNGINXの組み合わせで、サービス公開をよりセキュアに。ITがお届けするポッドキャストです。