はじめに
本記事は、GoFデザインパターン解説シリーズの1つです。
今回は、生成に関するパターンの中のAbstract Factory(抽象ファクトリー)パターンを、Javaのサンプルコードとともに解説します。
解決したい課題
前回解説したFactory Methodパターンは「1種類の製品」を生成するものでしたが、実務では「互いに関連する複数の製品を、組み合わせを間違えずにセットで生成したい」という場面がよくあります。
例えば、UIコンポーネントを「Windows風」「macOS風」のようにテーマ(見た目のファミリー)ごとに切り替えられるアプリを考えます。
ボタン(Button)・チェックボックス(Checkbox)といった複数の部品が存在し、これらを「Windows風のボタンと、macOS風のチェックボックス」のように異なるテーマ同士で混在させてしまうと、見た目が統一されずに壊れてしまいます。
Abstract Factoryパターンは、関連する複数の製品群を、一貫性を保ったまままとめて生成する専用のファクトリーを用意することで、この「組み合わせミス」を構造的に防ぎます。
クラス構成
- AbstractProduct(抽象製品): 各製品カテゴリ(Button、Checkbox等)の共通インターフェース
- ConcreteProduct(具体的な製品): 各テーマにおける、具体的な製品の実装
- AbstractFactory(抽象ファクトリー): 関連する製品群を生成するメソッド群を持つインターフェース
- ConcreteFactory(具体的なファクトリー): 特定のテーマに属する製品群だけを生成するクラス
Javaでの実装例
AbstractProduct:各部品の共通インターフェース
public interface Button {
void render();
}
public interface Checkbox {
void render();
}
ConcreteProduct:Windows風の部品
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("[Windows風] 四角いボタンを描画");
}
}
public class WindowsCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("[Windows風] 四角いチェックボックスを描画");
}
}
ConcreteProduct:macOS風の部品
public class MacButton implements Button {
@Override
public void render() {
System.out.println("[macOS風] 角丸ボタンを描画");
}
}
public class MacCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("[macOS風] 角丸チェックボックスを描画");
}
}
AbstractFactory:関連する部品群を生成するインターフェース
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
ConcreteFactory:テーマごとのファクトリー
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
利用側のコード
public class Application {
private final Button button;
private final Checkbox checkbox;
// ファクトリーを1つ受け取るだけで、テーマの一貫性が保証される
public Application(GUIFactory factory) {
this.button = factory.createButton();
this.checkbox = factory.createCheckbox();
}
public void renderUI() {
button.render();
checkbox.render();
}
}
public class Main {
public static void main(String[] args) {
String os = "windows"; // 実際には実行環境の判定結果などが入る想定
GUIFactory factory = os.equals("windows") ? new WindowsFactory() : new MacFactory();
Application app = new Application(factory);
app.renderUI();
}
}
実行結果:
[Windows風] 四角いボタンを描画
[Windows風] 四角いチェックボックスを描画
Applicationクラスは、GUIFactoryという抽象的な型としてファクトリーを受け取っているため、WindowsButtonやMacButtonといった具体的なクラス名を一切知りません。
渡すファクトリーをWindowsFactoryからMacFactoryに差し替えるだけで、ボタンもチェックボックスも一貫してmacOS風に切り替わります。
「Windows風のボタンとmacOS風のチェックボックスが混在する」ような事故は、この構造上そもそも起こりえません。
Factory Methodパターンとの関係
Abstract Factoryは、しばしば複数のFactory Methodの集合体として実装されます。
実際、上記のGUIFactoryインターフェースが持つcreateButton()・createCheckbox()は、それぞれが前回解説したFactory Methodの考え方そのものです。
「1つの生成メソッドをサブクラスで差し替える」のがFactory Method、「複数の生成メソッドをまとめて持つオブジェクトごと差し替える」のがAbstract Factory、という関係性で捉えると理解しやすくなります。
使用場面
- 複数のプラットフォーム・テーマ・環境に対応するUIコンポーネント群
- DB接続処理で、DBの種類(MySQL/PostgreSQL等)ごとに、関連する複数のクラス(Connection・Command・Adapter等)をセットで切り替えたい場合
- 「一貫性のあるファミリー」として複数のオブジェクトを扱う必要があり、組み合わせのミスを構造的に防ぎたい場合
まとめ
| 項目 | 内容 |
|---|---|
| 解決する課題 | 関連する複数の製品群を、一貫性を保ったまままとめて生成したい(組み合わせミスを防ぎたい) |
| 実現方法 | 関連する生成メソッド群を持つファクトリーインターフェースを定義し、テーマごとに実装を切り替える |
| Factory Methodとの関係 | Abstract Factoryは、複数のFactory Methodをまとめたオブジェクトとして実装されることが多い |
| メリット | 利用側のコードは具体的なクラス名を意識せず、ファクトリーの差し替えだけでテーマを一括切り替えできる |
おすすめ書籍
GoFの23パターンをより深く学びたい方には、以下の書籍がおすすめです。
Java言語のサンプルコードとUMLを使い、初心者にもわかりやすく解説されています。
Java言語で学ぶデザインパターン入門 第3版 [ 結城 浩 ]
※本リンクはアフィリエイトリンクを含みます。


