プログラミングマガジン

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

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

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

05.12

  • miyabisan2
  • コメントを書く

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

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

組み合わせて使う多数のサブクラス群を、まとめて交換できるようにするパターンです。

メリット?

実行するメインプログラムを修正することなく、サブクラス群を環境変化に伴って交換することができることです。

典型的な利用例

  • OSによって、一部のクラスの作りを変更したい場合
  • SQL文を、DBMSのパッケージによって変更したい場合

どのようなクラス構成になるのか?

「環境のスーパークラス」を作っておき、OSやDBMSによって、異なる別々のサブクラスを作ります。

サブクラスのオブジェクト生成を専門に行うクラス(ファクトリクラス)を作り、そのクラス内で、ペアの関連するクラスをまとめてnewします。

Factory Methodとの違いは?

Factory Methodパターンと、構造や概念が少し似ていますよね。

ただ、Factory Methodと異なり、片方のクラスにもう片方のクラスのnewを任せるのではなく、newする専門のクラスが、関連するサブクラスのnewをまとめて実施するという点です。

また、Factory Methodでは、基本的に2つのサブクラスのペアでしたが、3つでも4つでも、サブクラスの関連を拡張しやすいという点も特徴です。

参考までに、「Factory Method」については、下記の記事で解説しています。

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

どのように使うのか?

利用したいメインプログラム側では、そのファクトリクラスを呼びます。

明示的に特定のクラスをnewしていないので、後で別のファクトリクラスのクラスに置き換えるだけで、サブクラス群もまるまる交換することが可能になります。

実際に実装してみる。

まずは、イメージとして、「Factory Method」パターンでも使った下記の例を「AbstractFactory」パターンにも当てはめてみます。

完成後のクラスのイメージはこんな感じです。

Main.java(クラスを利用するプログラム)

「AbstractFactory」で使用するメインプログラムです。このプログラムではクラスをnewしないので、別のクラスに差し替えた場合でも、このクラスを修正する必要がなくなります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package AbstractFactory;
 
public class Main {
 
public static void main(String args[]) {
 
MadogutiFactory madogutifact = MadogutiFactory.getFactory("取引先の社長");
System.out.println("取引先の社長がいらっしゃいました。"+ madogutifact.createDepartment().getName() +
"の" + madogutifact.createTantosha().getName() +"さん、対応お願い致します。" );
 
MadogutiFactory madogutifact2 = MadogutiFactory.getFactory("内定者");
System.out.println("内定者の方がいらっしゃいました。"+ madogutifact2.createDepartment().getName() +
"の" + madogutifact2.createTantosha().getName() +"さん、対応お願い致します。" );
 
}
}

MadogutiFactory.java(サブクラス群をまとめて作る専用のクラスの親)

これを、Mainメソッドから呼びます。どちらのサブクラス群をnewするかは、引数でもらう変数で分岐させています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package AbstractFactory;
 
 
/**
* ファクトリの抽象クラスです。
*/
public abstract class MadogutiFactory {
 
abstract Department createDepartment();
abstract Tanto createTantosha();
 
public static MadogutiFactory getFactory(String Visitor) {
if(Visitor.equals("取引先の社長")) {
return new EigyoFactory();
}else if(Visitor.equals("内定者")) {
return new JinjiFactory();
}else {
return null;
}
}
 
}

EigyoFactory.java(サブクラス群をまとめて作る専用のクラスの子1)

1
2
3
4
5
6
7
8
9
10
11
12
13
package AbstractFactory;
 
public class EigyoFactory extends MadogutiFactory {
 
Department createDepartment(){
return new EigyoDepartment();
}
 
Tanto createTantosha(){
return new EigyoTanto();
}
 
}

JinjiFactory.java(サブクラス群をまとめて作る専用のクラスの子2)

1
2
3
4
5
6
7
8
9
10
11
12
13
package AbstractFactory;
 
public class JinjiFactory extends MadogutiFactory {
 
Department createDepartment(){
return new JinjiDepartment();
}
 
Tanto createTantosha(){
return new JinjiTanto();
}
 
}

Department.java(サブクラス1の親)

1
2
3
4
5
6
package AbstractFactory;
 
public abstract class Department {
 
abstract String getName();
}

EigyoDepartment.java(サブクラス1の子1)

1
2
3
4
5
6
7
8
9
package AbstractFactory;
 
public class EigyoDepartment extends Department{
 
public String getName(){
return "営業部";
}
 
}

JinjiDepartmentjava(サブクラス1の子2)

1
2
3
4
5
6
7
8
9
package AbstractFactory;
 
public class JinjiDepartment extends Department{
 
public String getName() {
return "人事部";
}
 
}

Tanto.java(サブクラス2の親)

1
2
3
4
5
6
7
package AbstractFactory;
 
public abstract class Tanto {
 
abstract String getName();
 
}

EigyoTanto.java(サブクラス2の子1)

1
2
3
4
5
6
7
8
9
package AbstractFactory;
 
public class EigyoTanto extends Tanto {
 
public String getName() {
return "鈴木高弘";
}
 
}

JinjiTanto.java(サブクラス2の子2)

1
2
3
4
5
6
7
8
9
package AbstractFactory;
 
public class JinjiTanto extends Tanto {
 
public String getName() {
return "小泉舞";
}
 
}

 実行結果

Abstract Factoryを使う上での注意点

Factory Methodと同様にあくまで、呼ぶサブクラスのペアが決まっている場合でのみしか効果を発揮しません。

複雑な条件で、呼ぶサブクラスが変わってくるようなシステムの場合は、あまり有効な手法ではないでしょう。

その場合は、メインプログラムで直接newした方がよいと思います。

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

関連記事

  1. 2018 04.30

    【Java】オブジェクト指向:インスタンス変数の初期化(コンストラクタ)、thisキーワード

  2. 2018 04.01

    【Javaサーブレット】セッション管理について

  3. 2018 04.21

    【JSP】EL式について

  4. 2018 03.31

    【Java】XMLから要素名を指定して値を取得するサンプル

  5. 2021 08.29

    【デザインパターン】「Observer」パターン、実装方法

  6. 2018 06.19

    【Java】例外処理の基本と、「独自例外」を作成するかのポイント

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

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

返信をキャンセルする。

【GoFのデザインパターン】「Factory Meth…

【GoFのデザインパターン】「Builder」ってどん…

RETURN TOP

著者プロフィール

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

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

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • 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
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

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