デザインパターン入門
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 64/87。
デザインパターンは、開発者がソフトウェアを構築する際に繰り返し直面する一般的な問題に対する、実証済みの解決策です。毎回車輪の再発明をするのではなく、これらの実績のあるテンプレートを適用して、繰り返し発生する設計上の課題を解決することができます。
デザインパターンを設計図と考えてください。これらはコピー&ペーストできる完成したコードを提供するものではありませんが、特定の種類の問題を解決するためにクラスやオブジェクトをどのように構成すべきかを記述したものです。これから学ぶパターンは、すでに習得しているOOPの概念、つまり継承(inheritance)、インターフェース(interfaces)、ポリモーフィズム(polymorphism)、およびコンポジション(composition)を活用します。
デザインパターンは、主に3つのカテゴリに分類されます:
| カテゴリ | 目的 | 例 |
|---|---|---|
| 生成 (Creational) | オブジェクトの生成方法 | Singleton, Factory, Builder |
| 構造 (Structural) | オブジェクトの構成方法 | Adapter, Decorator, Composite |
| 振る舞い (Behavioral) | オブジェクト間の通信方法 | Observer, Strategy, Command |
なぜデザインパターンを学ぶのでしょうか?デザインパターンは、他の開発者との共通の語彙を提供してくれます。「ここではFactoryを使おう」と言うだけで、複雑なアイデアを即座に伝えることができます。また、「実装ではなくインターフェースに対してプログラミングする」といった原則を適用することで、より柔軟でメンテナンス性の高いコードを書くのにも役立ちます。
今後のレッスンでは、SingletonやFactoryといった生成に関するパターンから始め、次にObserverやStrategyといった振る舞いに関するパターンへと進み、いくつかの重要なパターンを実装していきます。
チャレンジ
簡単3つのデザインパターンのカテゴリについての理解を示す、シンプルなパターン分類器を構築しましょう!パターンのカテゴリを分類し、その目的を説明するシステムを作成し、コードを複数のファイルに整理します。
以下の3つのファイルを作成します:
Pattern.java: すべてのデザインパターンのコントラクトを定義するPatternという名前のインターフェースを作成します。インターフェースには2つのメソッドを宣言する必要があります:パターンのカテゴリ(Creational、Structural、または Behavioral)を返すString getCategory()と、そのカテゴリのパターンの役割の説明を返すString getPurpose()です。PatternInfo.java:Patternインターフェースを実装する3つのクラスを作成します。各クラスはデザインパターンの1つのカテゴリを表します:CreationalPattern- カテゴリとして"Creational"を、目的として"How objects are created"を返す必要があります。StructuralPattern- カテゴリとして"Structural"を、目的として"How objects are composed"を返す必要があります。BehavioralPattern- カテゴリとして"Behavioral"を、目的として"How objects communicate"を返す必要があります。Main.java: パターン分類器を完成させましょう!1つの入力として、"Singleton"、"Factory"、"Adapter"、"Decorator"、"Observer"、または"Strategy"のいずれかのパターン名(String)を受け取ります。入力に基づいて、適切なパターンオブジェクトを作成します:
"Singleton"と"Factory"は Creational パターンです"Adapter"と"Decorator"は Structural パターンです"Observer"と"Strategy"は Behavioral パターンです
「インターフェースに対してプログラミングする」という原則を実践するために、パターンオブジェクトを
Pattern型(インターフェース)の変数に格納してください。その後、以下の3行を出力します:Pattern: [input pattern name]Category: [category from getCategory()]Purpose: [purpose from getPurpose()]
1つの入力として、デザインパターンの名前(String)を受け取ります。
このチャレンジは、レッスンで学んだ重要な洞察を強化するものです。デザインパターンは、解決する問題に基づいてカテゴリに分類されます。インターフェースを使用することで、「実装ではなくインターフェースに対してプログラミングする」という原則も練習しています。これはデザインパターンを非常に強力なものにしている核心的な概念です!
チートシート
デザインパターンは、ソフトウェア開発における一般的な問題に対する、実証済みの解決策です。これらは、特定の種類の問題を解決するためにクラスやオブジェクトをどのように構成するかを記述した設計図です。
デザインパターンは、主に3つのカテゴリに分類されます:
| カテゴリ | 目的 | 例 |
|---|---|---|
| 生成 (Creational) | オブジェクトの生成方法 | Singleton, Factory, Builder |
| 構造 (Structural) | オブジェクトの構成方法 | Adapter, Decorator, Composite |
| 振る舞い (Behavioral) | オブジェクト間の通信方法 | Observer, Strategy, Command |
デザインパターンは、開発者間での共通の語彙を提供し、「実装ではなくインターフェースに対してプログラミングする」といった原則を適用することで、より柔軟でメンテナンス性の高いコードを書くのに役立ちます。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String patternName = scanner.nextLine();
// TODO: Pattern型(インターフェース)の変数を宣言する
Pattern pattern = null;
// TODO: patternNameに基づいて、適切なパターンオブジェクトを作成する:
// - "Singleton" と "Factory" は Creational(生成に関する)パターン
// - "Adapter" と "Decorator" は Structural(構造に関する)パターン
// - "Observer" と "Strategy" は Behavioral(振る舞いに関する)パターン
// TODO: 以下の形式で出力を表示する:
// Pattern: [入力されたパターン名]
// Category: [getCategory() から取得したカテゴリ]
// Purpose: [getPurpose() から取得した目的]
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造