プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • デザインパターン
  • 【GoFのデザインパターン】「Factory Method」ってどんなパターン?
 
 
     
  • サーバー言語  
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【GoFのデザインパターン】「Factory Method」ってどんなパターン?

05.10

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

Factory Methodってどんなパターン?

複数に分割したクラスのインスタンスを生成する際は、それぞれコンストラクタを呼んで生成するのではなく、「片方のインスタンスは生成するが、もう片方のインスタンスは既に作成済みの片方のインスタンスに頼んで生成してもらうという」というのが基本方針になります。

通常、もう片方のクラス内でインスタンスを作ってくれるメソッドを「ファクトリメソッド」と呼びます。

どんなメリットがあるの?

クラスを複数のクラスに分割した場合は、それぞれ適切なペアのインスタンスを生成しなければならないということが、クラスによってはあたっりするものですよね。

特に、複雑度が高く、サブクラスの数が多いシステムの場合は、それが起こる可能性が高まります。

その際に、複雑なシステムになればなるほどどのペアでインスタンスを生成したらよいか、わからなくなりがちになりますが、このパターンを使うことで開発時にその迷いがなくなります。

前提条件

「Factory Methodパターン」を使うための前提条件としては、下記2つを満たしていることになります。

  1. 1つのまとまった機能を1つのクラスで作るのではなく、2つ以上のクラスに分解して作った場合
  2. その分割したクラスを、それぞれ継承させてサブクラスとして使う場合。

どんな時に使うと効果的なのか?

上記、二つを満たせばFactory Methodパターンを使うことはできますが、特に効果を発揮するのは、下記2つの条件を満たしたクラスを作る場合です。

  • 継承させたサブクラスが、今後数が増えると想定される場合
  • (一番大事)サブクラス同士をペアで使うことが、明確である場合

特に重要なのが、二つ目です。サブクラス同士がペアで使うことが明確でなければ、開発者がイマイチ理解できず、せっかく作ったクラスが台無しになってしまいます。

実際に使ってみましょう。

イメージ図

会社に訪問者が来て、その訪問者に応じて、応対する担当部署を振り分けるクラスを例に実装してみましょう。

クラス図のイメージ

クラス図にすると下記のような感じです。(小さくて見難い場合は、お手数ですが拡大してご覧下さい。)

前提条件で書いたようにしています。

  • 二つの親クラスを作っている。(「訪問抽象クラス」、「部署抽象クラス」)
  • それぞれサブクラスを持っている。

実装する。

AbstractDepartment.java

1
2
3
4
5
6
7
8
9
10
11
package factoryMethodSample;
 
/**
* 部署抽象クラス
*/
public abstract class AbstractDepartment {
 
/* 接待する抽象メソッド */
abstract void reception();
 
}

AbstractVisit.java

1
2
3
4
5
6
7
8
9
10
package factoryMethodSample;
 
/**
* 訪問抽象クラス
*/
public abstract class AbstractVisit {
 
public abstract AbstractDepartment call();
 
}

EigyoDepartment.java

1
2
3
4
5
6
7
8
9
package factoryMethodSample;
 
public class EigyoDepartment extends AbstractDepartment {
 
public void reception() {
System.out.println("ようこそ、いらっしゃいましたわが社へ。");
}
 
}

JinjiDepartment.java

1
2
3
4
5
6
7
8
9
package factoryMethodSample;
 
public class JinjiDepartment extends AbstractDepartment {
 
public void reception() {
System.out.println("内定おめでとうございます。今日は何でも質問してくださいね。");
}
 
}

Madoguti.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package factoryMethodSample;
 
/**
* 受付窓口クラス
*/
public class Madoguti {
 
public static void main(String[] args) {
 
//訪問者が取引先だった場合
AbstractVisit adp = new TorihikisakiVisit();
AbstractDepartment adt = adp.call();
adt.reception();
 
//訪問者が内定者だった場合
AbstractVisit adp2 = new NaiteishaVisit();
AbstractDepartment adt2 = adp2.call();
adt2.reception();
 
}
 
}

NaiteishaVisit.java

1
2
3
4
5
6
7
8
9
package factoryMethodSample;
 
public class NaiteishaVisit extends AbstractVisit{
 
public JinjiDepartment call() {
return new JinjiDepartment();
}
 
}

TorihikisakiVisit.java

1
2
3
4
5
6
7
8
9
package factoryMethodSample;
 
public class TorihikisakiVisit extends AbstractVisit {
 
public EigyoDepartment call() {
return new EigyoDepartment();
}
 
}

実行結果

 

Factory Methodのポイント

呼び出す元となるプログラムでは、スーパークラスのオブジェクト名に代入しています。

//訪問者が取引先だった場合

AbstractVisit(スーパークラス) adp = new TorihikisakiVisit()(子クラス);

これは、「オブジェクト指向」の基本でもある「ポリフォルリズム:多様性」ですね。

多様性のメリットとしては、「子クラスの数を増やしても、あいまいなものと捉えて、ソースコードの重複を減らせる」ということでした。

なお、多様性については、下記の記事でも解説していますので、参考になさってください。

【オブジェクト指向】多様性(ポリモーフィズム)のメリット

それに加えて、「Factory Method」のデザインパターンを使うと、「サブクラス間にペアがある場合は、適切なペアのクラスをインスタンス化できる」というメリットを体感いただきました。

今回の例で言えば、「取引先が着たら、営業部をインスタンス化する」、「内定者が着たら、人事部をインスタンス化する」というようにですね。

スポンサーリンク
  • 2018 05.10
  • miyabisan2
  • コメントを書く
  • Java, デザインパターン
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 05.03

    【Java】インナークラスについて(メンバクラス、ローカルクラス、匿名クラス)

  2. 2018 05.13

    【GoFのデザインパターン】「Proxy(プロキシ)」ってどんなパターン?

  3. 2018 04.22

    【Java】デザインパターンやクラス設計の基本

  4. 2018 05.04

    【Webセキュリティ】ハッシュ関数(digest)、実装方法、パスワード運用について

  5. 2018 04.22

    【Webアプリ】設計の基本(Java)

  6. 2018 04.22

    【JSP】JSTLで繰り返し文を使うには?

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Java】ArrayListで要素を順に取り出す4つ…

【GoFのデザインパターン】「Abstract Fac…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Git
  • GitLab
  • GraphQL
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • WebRTC
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 業務知識
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー