5分で分かるJavaデザインパターン

「いつも読みづらいソースコードを書いてしまう」、「システムが複雑すぎて、調査に時間がかかる」
もしかしたら、それはシステムの設計が悪いせいかもしれません。その状態では、プログラマがどんなに頑張っても、なかなか分かりやすいソースコードにはならないもの。“デザインパターン”を学ぶことで、もっと美しい設計を実現していきましょう!

デザインパターンって何?

20160304_1

デザインパターンとは、「オブジェクト指向において、よく使われる設計をパターン化したもの」です。

これを適用させると、プログラムが再利用しやすく、かつ読みやすいものとなります。デザインパターンを正しく理解するためは、オブジェクト指向の知識を持っていることが大前提。そこでまずは、オブジェクト指向とはどのようなものだったか、おさらいをしておきましょう。

オブジェクト指向では、いくつかのオブジェクトを生成し、各オブジェクトの役割分担を明確にします。「データベースへのアクセスをおこなう」、「各コンポーネントのコントロールをする」などです。そして、それらのオブジェクトの組み合わせによって処理を実現します。

20160304_2

■オブジェクト指向のメリット

オブジェクト指向のメリットとして、「再利用性の高さ」「信頼性の向上」があげられます。

たとえば、ユーザの情報をもったデータベースにアクセスする場合には、「ユーザDAO(データ・アクセス・オブジェクト)クラス」を作成し、そのクラスをさまざまな箇所で呼び出すことで処理を実現するのです。これによって、「データベースへ接続する処理を、各クラスのなかでイチから実装する」ということがなくなります。一度書いたプログラムを「再利用している」というわけです。

また、ユーザDAOクラスは複数の箇所で呼び出されるため、なんども動作のテストが行われます。プログラムは、使われれば使われるほどバグを検出できる可能性が高くなり、品質が高くなっていくのです。これが「信頼性の向上」につながります。

20160304_3

しかし、このように再利用性の高いクラスを設計することは簡単ではありません。事実、過去には数多くのエンジニアたちが設計を失敗し、スパゲッティコードと呼ばれる、ぐちゃぐちゃに絡まったソースコードを生み出してきました。

そのような失敗をしないためにも、「上手な設計をしている人たちの考え方をまねて、自分たちも同じような設計ができるようになりたい」という発想が生まれます。その、「良い設計を実現するためのパターンをまとめたもの」がデザインパターンなのです。

導入するとどんなメリットがあるの?

20160304_4

それでは、デザインパターンを導入するとどのようなメリットがあるのでしょうか?

具体的には、次の3つの「○○しやすくなる!」があります。

■機能の追加・更新がしやすくなる!
デザインパターンを適用し、良い設計になっていると、プログラムはとても再利用しやすいものとなります。そのため、機能の追加・更新がよりかんたんに実装できるのです。

■バグの原因を特定しやすくなる!
各オブジェクトの役割が明確なことによる、副次的な効果です。たとえば、データベースへ接続する処理で失敗している場合、データベースに関連するオブジェクトだけを調べればよいため、範囲を簡単にしぼりこむことができます。ソースコード全体を調査しなければいけないケースと比較すると、その差は明らかです。

■エンジニア同士でコミュニケーションをとりやすくなる!
エンジニア同士がデザインパターンの知識を持っていると、設計に関する会話がよりスムーズになります。つまり、「この箇所は○○というパターンを使用している」、「ここは○○パターンにしてみたらどうだろう」というように、認識のすり合わせができるようになるのです。

代表的なパターン

20160304_5

デザインパターンがどのようなものか、なんとなく分かってきましたね。ここからは、いくつかの代表的なパターンを、サンプルコードつきでご紹介していきましょう。

■Singleton(シングルトン)パターン

あるクラスのインスタンスが、プログラム内に1つしかないことを保証したいケースがあります。それを実現するために、全てのメンバーに「インスタンスを生成するなよ!」と注意をうながし、厳密にレビューをするということはあまり現実的ではないですよね。そんなとき、効果があるのがSingletonパターンです。

Singletonパターンではまず、コンストラクタの識別子をprivate(プライベート)にします。private識別子のついたものは、外部クラスからの呼び出しが拒否されるため、新しいインスタンスを作り出すことができなくなるのです。これによって、Moonクラスのインスタンスは

によって生成されている1つだけに限定されます。
Moonクラスのインスタンスが欲しいときには、

として取得せざるをえないようなつくりになっているのです。

■Facade(ファサード)パターン

アプリケーションを開発していると、「Aの処理とBの処理は必ずセットで実施しなければならない」というケースがあります。たとえば、「ユーザが退会する際には、併せてメールマガジンを送るのもストップする」といった感じです。

プログラマが全ての組み合わせを把握できていればよいのですが、万が一なにか1つを忘れてしまった場合、それは重大なバグにつながります。そのような事態を防ぐため、「一連の手順をセットで実行してくれるクラスやメソッド」を作って利用するのがFacadeパターンです。

Facadeクラスのsecede(退会する、の意)メソッド内部では、さきほど説明した「ユーザが退会する」、「メールマガジンを送るのもストップする」という処理をセットにして実施しています。このため、他のクラスはFacadeクラスの持つsecedeメソッドを呼び出すだけでよくなり、より実装がシンプルになるのです。

■Flyweight(フライウェイト)パターン

インスタンスを作れば作るほど、プログラムの動作は重たくなります。これはつまり、「無駄なインスタンスを生成しなければ、プログラムの動作が軽くなる」ということの裏返し。Flyweightパターンは、そのような目的のために使用されるパターンです。

Flyweightとは英語で「フライ級」を意味し、ボクシングなどの体重階級の中でもっとも軽い部類のこと。つまり、それだけ動作を軽量化できるパターンなのです。

FlyweightクラスのgetSomeClassメソッドの中では、「mapの中にその名前のインスタンスがふくまれているかどうか」のチェックをしています。
ふくまれている場合はそのインスタンスを返し、わざわざ新しく作り直すことはありません。これによって無駄なインスタンスの生成を防ぎ、動作を軽くすることができるのです。

おわりに

先人の知恵がぎっしりつまったデザインパターン。そこには、プログラムをよりよい設計にするためのノウハウがあふれています。
特にここで出てきたパターンは、使われる頻度がとても高いものです。適用すれば、あなたの書いているプログラムをもっと良くできること間違いなし!デザインパターンを使い、より優れた設計を実現していきましょう!

関連記事:5分で分かるガベージコレクション


最新情報はFacebook/Twitterをフォロー!


この記事を書いた人:ぞの

img_zono

Webアプリケーションエンジニアとして様々な現場に参画し、多種多様な言語を習得。エンジニアとしての強みは汎用性の高さと、メンバーとコミュニケーションを取り合いながら円滑に案件を進められること。趣味は音楽と将棋。Ruby愛好家。Twitter : @zono1009

関連する記事

facebook

案件情報や最新記事をお届けします。
ぜひチェックしてみてください。