Factory Method

  • 親クラスでインスタンスの生成方法を定め、具体的に何をどうやって作るかは子クラスで定めるようなパターン
    • 生成したいオブジェクトのコンストラクタを呼び出してインスタンスを生成するのではなく、親クラスに定義された生成用のメソッドを呼び出してインスタンスの生成を行う
  • Template methodを応用したパターン
  • 「継承」を利用したパターン
  • ProductConcreteProduct

メリット・デメリット

メリット
  • オープンクローズドの原則に違反することなく新しいProductを追加することができる
  • オブジェクトの利用側とオブジェクトの結びつきを弱くすることができる
デメリット
  • 簡単な生成処理の場合はFactory Methodを使用しない方がコードがシンプルになる

用途

  • 類似した複数種類のオブジェクトを生成する必要がある場合
    • オープンクローズドの原則に違反することなく別のオブジェクトの追加が可能
  • オブジェクトの生成ロジックが複雑な場合
    • createメソッドを呼び出すだけで複雑なロジックを記述せず生成可能
  • Productの種類や生成手順が頻繁に変更される可能性がある場合
    • 利用側とProductの結びつきが弱いので、変更に強い設計となる

デザインパターンの種類

生成に関するデザインパターン

例(Mermaid)

例1
  • Creator
    • Productを生成する抽象クラス
    • Productの生成を行うcreateメソッド
    • 具体的な生成方法を実装するためのAPIを提供
  • ConcreteCreator
    • Creatorを継承したクラス
    • 製品生成のための具体的な方法を実装
    • ConcreteProductクラスのインスタンスを返却
  • Product
    • Creatorのオブジェクト生成メソッドで生成される抽象クラス or インターフェース
    • 生成される製品が持つべきAPIを定義する
  • ConcreateProduct
    • Productを継承(実装)したクラス
    • ProductAPIに沿った具体的な製品の機能を実装
classDiagram
	class Creator {
		<<abstract>>
		create()
		factoryMethod()
	}
	class Product {
		<<abstract>>
		method1()
		method2()
	}
	class ConcreteCreator {
		factoryMethod()
	}
	class ConcreteProduct {
		method1()
		method2()
	}
	Creator <|-- ConcreteCreator
	Product <-- Creator
	Product <|-- ConcreteProduct
	ConcreteProduct <-- ConcreteCreator
例2

クレジットカードを作成する例

classDiagram
	class CreditCardFactory {
		<<abstract>>
		create()
		createCreditCard(owner: string)$
		registerCreditCard(creditCard: CreditCard)$
	}
	class CreditCard {
		<<abstract>>
		getOwner()
		getCardType()$
		getAnnualCharge()$
	}
	class PlatinumCreditCardFactory {
		createCreditCard(owner: string)
		registerCreditCard(creditCard: CreditCard)
	}
	class Platinum {
		getCardType()
		getAnnualCharge()
	}
	CreditCardFactory <|-- PlatinumCreditCardFactory
	CreditCard <-- CreditCardFactory
	CreditCard <|-- Platinum
	Platinum <-- PlatinumCreditCardFactory