1. TOP
  2. エンスタマガジン
  3. 学習
  4. Javaのデザインパターンとは?全23種の概要と特徴について徹底解説!

Javaのデザインパターンとは?全23種の概要と特徴について徹底解説!


はじめまして、エンジニアスタイル編集部です!

コラムページでは、ITフリーランスに向けてお役立ち情報を発信します。Twitterではホットな案件を紹介してまいりますので、ぜひフォローをお願いいたします!
本記事が、皆様の参考になれば幸いです。

経験がまだ少ない方にもわかりやすく説明するために、初歩的な内容も記載しております。記事も長いので、実務経験豊富な方は、ぜひ目次から関心のある項目を選択してください。

エンジニアスタイルは、最高単価390万円、国内最大級のITフリーランス・副業案件検索サービスです。Javaのフリーランス・副業案件一覧を以下からご覧いただけますのであわせてご確認ください。

デザインパターンとは?

デザインパターンとは、オブジェクト指向の言語で使用頻度の高い設計を、パターンとしてまとめたものです。

1995年に出版された、GoF(Gang of Four)の『オブジェクト指向における再利用のためのデザインパターン』が特に有名です。この書籍がきっかけとなり、広く認知されるようになりました。

GoF(Gang of Four)のデザインパターンは、過去のエンジニアが積み上げてきた経験に基づくベストな設計が、3つのカテゴリに分けてまとめられています。デザインパターンといえば、GoF(Gang of Four)の書籍でまとめられている項目を指すことが多いので、覚えておきましょう。

JavaではGoFも使われますが、Java EEアプリケーション用のDAOやDTOのようなデザインパターンもあります。DAO(Data Access Object)パターンを使うと、データベースにアクセスするためのオブジェクトを作れます。DTO(Data Transfer Object)は、データを渡すためのオブジェクトを作り、やり取りができるようにするパターンです。

次に、デザインパターンを利用するメリットを解説します。

デザインパターンのメリット

デザインパターンを利用するメリットは、以下の通りです。

  • コミュニケーションがスムーズになる
  • 読みやすいコードになる
  • 再利用ができて効率化に有効

1つ目のメリットは、ミスコミュニケーションのリスクを減らせることです。デザインパターンを活用すると、チーム内で共通の認識を持つことができ、コミュニケーションがスムーズになります。たとえば、指示を出す際も「Abstract Factoryを使いましょう。」と言えば理解できるため、指示が正しく伝わりやすくなります。

2つ目は、誰でも読みやすいコードが書けることです。デザインパターンを学んできたエンジニアは多く、デザインパターンを使ったコードを書くことで可読性が上がります。

特に経験が浅いエンジニアは、読みやすいコードを書くことは難しいでしょう。デザインパターンを使えば、経験が浅いエンジニアでも、質の良いコードを書けるようになります。加えて、良い設計を学べるので、コーディングのレベルアップも期待できます。

3つ目は、再利用しやすく効率的に業務ができることです。デザインパターンは過去のエンジニアの経験から、ベストと思われる考え方がまとめられています。そのため、誰でも再利用しやすく、デザインパターンを駆使することで、効率の良いコーディングが可能です。

デザインパターン一覧

デザインパターンは全部で23個あり、以下の3つのカテゴリに分類できます。

  • オブジェクトの生成に関するパターン
  • プログラムの構造に関するパターン
  • オブジェクトの振る舞いに関するパターン

それぞれのカテゴリのパターンを、詳しく解説します。

オブジェクトの生成に関するパターン

オブジェクトの生成に関するパターンには、どのようなものがあるのでしょうか。5つ解説します。このパターンを使えるようになると、効率よくオブジェクトを管理できるようになります。

Abstract Factory

Abstract Factoryは、同じ種類のオブジェクトを集め、まとめたいときに使えるパターンです。一致しているオブジェクトを、正しくピックアップしてまとめるので、関連性のないオブジェクト同士を組み合わせるミスを防げます。

Builder

Builderは部品となるオブジェクトが多数ある状態で、それらを組み合わせるときに適しています。Builderを使うことで、あちこちに分散しているオブジェクトの収集が可能です。自分で1つ1つ探す必要がなく、複雑なオブジェクトの組み立てが簡単になります。

単にオブジェクトを集めるだけでなく、組み立て方に間違いや不備がないことをチェックする機能も設定できます。

Factory Method

Factory Methodはオブジェクトを作るための仕組みを、スーパークラスで決めておけるパターンです。ルールはスーパークラスで設定しておき、実際の処理はその下の層である、サブクラスにおこなわせます。

オブジェクトの生成と処理を分けることで、機能を追加しやすくなります。

Prototype

Prototypeは既にあるオブジェクトをコピーして、新しいオブジェクトを作成可能です。オブジェクトを単純にコピーした場合、フィールドの一部が非公開になっていると、正しくコピーできないことがあります。

Prototypeを使うとこの問題を解決できるので、同じクラス内で、複数のオブジェクトを作りたい場合に有効です。

Singleton

Singletonは1つのクラスにつき、1つのオブジェクトを持つように決めるパターンです。コンストラクタの識別子をprivateにすると、外部のクラスから呼び出せなくなり、新しいオブジェクトが作れなくなります。

これによって、データベースやファイルへのアクセスの制限が可能になり、オブジェクトを勝手に変更することができなくなります。

プログラムの構造に関するパターン

次に、プログラムの構造に関するパターンを7つ紹介します。これを活用することで、複雑なプログラムもシンプルな構造にできます。

Adaptor

Adaptorは、互換性のないクラス同士を繋げられるようにするパターンです。繋げたいオブジェクトのインターフェースを、別のオブジェクトが認識できるようにする、変換アダプターのような役割を果たします。一方向だけでなく、双方向で変換できるアダプターを作ることも可能です。

Bridge

Bridgeは、機能を追加するクラスと実装するクラスを分けて、その間を繋ぐ機能を持ちます。機能のクラスと実装のクラスがすべて一緒になったコードでは、一部に変更を加えたい場合も、全体のバランスを考慮しなければなりません。そのため、少しの変更にも労力がかかります。

Bridgeを使うとクラスの役割が細かく分かれ、それぞれを独立させられるので、メンテナンスも簡単になります。

Composite

Compositeはオブジェクトをツリーのように繋げていき、それぞれを独立したオブジェクトとして使えるようにします。これは、フォルダとその中にあるサブフォルダやファイルのようなイメージです。

Compositeを使うと、実際の処理メソッドが入った具象クラスかどうかを気にする必要がなくなり、すべてのインターフェースで同じものを取り扱えるようになります。

Decorator

Decoratorは、新しい機能を追加するパターンで、マトリョーシカのように、1つ1つ機能をかぶせていくイメージです。Decoratorを使うことで、ほかのオブジェクトに変更を加えることなく、さまざまな機能を追加できます。

Facade

Facadeは窓口役となるクラスを設定し、リクエストが来たら、受付のクラスがそれぞれのクラスに指示を出すようにします。通販のようなもので、電話で注文をすると、オペレーターが受付をし、そのあと各部署に商品の準備をするよう指示が届くようなイメージです。

Facadeを組み込むと、1つの指示で必要な処理が実行され、複雑な処理もシンプルになります。そのため、一連の処理をセットで行う必要があるプログラムを作るときに便利です。

Flyweight

Flyweightはたくさんの小さなオブジェクトを、共有させながら読み込めるようにするパターンです。本当に必要な分だけのオブジェクトを作れば良く、都度メモリを消費して新しいオブジェクトを作る手間がなくなります。そうすることで、効率的に処理ができ、メモリ数も下げられることが利点です。

Javaには自動でメモリに空きを作る、ガーベジコレクションという機能がついており、メモリ容量が問題になることは少ないといえます。ただ、Flyweightは高品質なプログラムを作るために活用できるので、しっかりと覚えておきましょう。

Proxy

Proxyは、代理の役割を持つオブジェクトに、処理をさせるパターンです。基本的には代理のオブジェクトが処理をおこない、どうしても本体のオブジェクトにしかできない処理がある場合だけ引き渡します。

本体のオブジェクトへのアクセスを制限することで、元のオブジェクトの負荷を減らせる点がメリットです。Decoratorと似ていますが、Decoratorは機能を追加するのに対して、Proxyは本体の負担を軽減するための処理を追加する点で異なっています。

オブジェクトの振る舞いに関するパターン

3つ目のオブジェクトの振る舞いに関するパターンを見てみましょう。このパターンは全部で11個あり、活用することで状況に応じた処理がしやすくなります。

Chain of Responsibility

Chain of Responsibilityは、1つのオブジェクトだけではできない処理がある場合、ほかのクラスのオブジェクトに残りの処理を渡して、実行できるようにするパターンです。Chain of Responsibilityを使うと、一点に負荷が集中することがなくなり、それぞれの処理の独立性が進みます。

処理する立場のクラスも、そのクラスが責任を持つ処理の範囲だけを記述すれば良いので、コードがシンプルになります。

Command

Commandは、命令をオブジェクトとして扱うことで、さまざまなオブジェクトを組み合わせられるようにするパターンです。プログラムで多数の命令を送りたい場合、引数の数や種類を増やしますが、追加できる数には限度があります。

命令をオブジェクトにすれば、命令の追加や実行、削除の管理ができるようになることがメリットです。

Interpreter

Compositeと似ているパターンで、ある規則に基づいて書かれた構文をオブジェクトで表現します。そのオブジェクトを使い解析した結果に従って、処理をするパターンです。

Interpreterを使うと1つのクラスにつき、1つのルールが与えられます。解析した結果、分かった規則に合う処理をさせたい時に有効です。

Iterator

Iteratorを使うと、データの最初から最後までを、順番にスキャンできるようになります。オブジェクトの種類に関係なく、それぞれの要素を順序だててスキャンする方法を提供するためのパターンです。

Iteratorは人間がデータの数を把握していないときでも、すべての要素を順番にたどれる点がメリットです。

Mediator

Mediatorは、たくさんのオブジェクトの処理を整理し、オブジェクト同士が直接通信する機会を減らします。Mediatorは通信の流れと量を見て、適切な量のデータを流すように整理する役割を持っています。

空港の管制塔をイメージすると分かりやすいでしょう。空港ではパイロット同士が直接連絡を取らず、管制塔の係員が滑走路の様子を見ながら、飛行機の離着陸の管理をします。

オブジェクト間の通信を1箇所で管理することで、メンテナンスがしやすくなる点がメリットです。加えて、それぞれのオブジェクトを、再び利用することも容易になります。

Memento

Mementoは、ある時点でのオブジェクトのスナップショットを撮っておき、前のオブジェクトの状態を復元できるようにするパターンです。非公開のフィールドも含め、必要なオブジェクトの情報だけをピックアップし、完全なコピーを作成します。

Prototypeのように、すべてをそのままコピーするわけではないので、無駄がありません。ある時点まで戻って、もう一度作業したい場合に便利です。

Observer

Observerでは、監視されるサブジェクトと、監視するオブザーバーの2つの役割が存在します。Observerはサブジェクトの状態に変更があった場合、自動的にオブザーバーへ通知できるパターンです。既にあるコードを変更せずに、機能を追加できることがメリットです。

State

Stateはオブジェクトの内容に変更があったときに、動作も変化させるパターンです。状態をクラスで表すパターンなので、状態に応じて柔軟に動作を変える必要があるときに使えます。

たとえば、いくつもの条件分岐があるコードをそのまま書くと、構造が複雑になりメンテナンスしにくくなります。Stateで1つ1つの状態を、個々のクラスで表すことで、シンプルな構造になることが利点です。

Strategy

ここでいうStrategyとは、アルゴリズムのことです。Strategyは状況に応じて、使用するアルゴリズムを変化させられるパターンです。アルゴリズムを別クラスとして作ることで、プログラムの柔軟性が増し、追加や変更が簡単になります。加えて、メンテナンスがしやすくなることもメリットです。

Template Method

Template Methodは、スーパークラス内でアルゴリズムのテンプレートを作成し、実際の処理内容をサブクラスに記述するパターンです。

サブクラスにはそのテンプレートを元にして、具体的な処理の内容を書きます。Template Methodは同じようなプロセスを使う処理を、統一したいときに使えます。

スーパークラスに重要な部分が集約されているので、サブクラスの記述がシンプルになる点が特徴です。バグが起きた時は、TemplateMethodを修正すれば良く、効率的な構造になります。

Visitor

Visitorでは、データ構造と振る舞いを分けることが可能です。データ構造を移動するビジターのクラスを設置し、ビジターが処理をおこなうようにします。新規の処理が必要になったときは、新しいビジターを用意します。

データ構造と処理が別々になることで、処理の追加や変更が簡単になることがメリットです。

デザインパターンを学ぶのにオススメの書籍

デザインパターンを学ぶのに、オススメの書籍は以下の3つです。

著者:結城浩

出版社:ソフトバンククリエイティブ

著者:エリック・フリーマン、エリザベス・フリーマン

出版社:オライリージャパン

著者:アラン・シャロウェイ、ジェームズ・R・トロット

出版社:ピアソン・エデュケーション

それぞれを詳しく見てみましょう。

Java言語で学ぶデザインパターン入門

『Java言語で学ぶデザインパターン入門』は、デザインパターンを初めて学ぶ方におすすめです。23個のデザインパターンの基礎が丁寧に解説されていて、それぞれの役割を理解するために役立ちます。デザインパターンの概念やルールはもちろんのこと、実際のコードを用いた例も掲載されています。

デザインパターンの説明は言葉だけだとイメージしにくいですが、『Java言語で学ぶデザインパターン入門』は、図解を多く使用しており、理解しやすいことが魅力です。説明も初心者が読むことを考えた言葉で書かれているので、デザインパターンを初めて勉強する方は、読んでおきたい1冊です。

参照:Java言語で学ぶデザインパターン入門

Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本

『Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本』は、イラストが多くイメージで理解できます。

イラストの多さから誰でも手に取りやすいですが、十分な情報量のある本格的な書籍です。デザインパターンを初めて学ぶ方だけでなく、少し学んだ経験のある方にもおすすめです。

実際のプロジェクトで使われた事例を多く使用し、解説しているので、仕事に活かしやすい内容が学べます。

参照:Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本

デザインパターンとともに学ぶオブジェクト指向のこころ

『デザインパターンとともに学ぶオブジェクト指向のこころ』は、オブジェクト指向の考え方を、分かりやすく解説している本です。

デザインパターンは、特に重要なものをピックアップして、詳しく解説しています。本の中には練習問題があり、実際に手を動かしながら学べることが特徴です。原書は英語なので日本語訳に少しクセがあり、最初は読みにくい箇所やイメージのつきにくい箇所があるでしょう。

ただ、内容は充実しているため、Javaを学ぶ方であれば読んでおきたいところです。デザインパターンを少し勉強した経験があり、デザインパターンを使いながら、オブジェクト指向の理解を深めたい方におすすめです。

参照:デザインパターンとともに学ぶオブジェクト指向のこころ

まとめ

この記事では、Javaのデザインパターンの概要やメリット、23のパターンなどについて解説しました。

デザインパターンを知ることで、経験豊富なエンジニアの考え方を知ることができ、シンプルでメンテナンスや変更のしやすいコードが書けるようになります。

さらに、デザインパターンを使いこなせると、仕事の幅も広がり、キャリアの選択肢も増えるでしょう。今回紹介したオススメの書籍を使って、ぜひデザインパターンの勉強をしてみてください。

SNSシェア
CATEGORY
学習
新規会員登録エージェントとの初面談1社につきAmazonギフト券3,000円分全員にプレゼント!

あわせて読みたい関連記事


エンジニアスタイルでJavaの案件を見る

おすすめ&新着求人・案件


各種SNSで情報を
発信中フリーランスで働くエンジニアに役立つ情報を発信しています。
フリーランス求人・案件の選び方や注意点、単価を上げるコツなどをエンジニアスタイルの編集部が発信しています。
フォロー・友達に追加していただき最新の情報をGETしてください。