Factoryって採番とかで使えばいいの?

Factoryとは

Factoryはソフトウェア設計パターンの1つで、オブジェクトの生成をカプセル化することを目的としています。Factoryパターンは、クライアントが直接インスタンスを作成する代わりに、特定のメソッドを通じてオブジェクトを生成するために使用されます。これにより、オブジェクトの作成に関連するロジックを1か所にまとめ、コードの再利用性を高め、保守性を向上させます。

Factoryパターンには主に3つのバリエーションがあります。

  1. Simple Factory: これは実際にはデザインパターンとは考えられていませんが、ファクトリのコンセプトを導入するための基本的な方法です。Simple Factoryは、一連の同様のオブジェクトを生成するためのインターフェースを提供するクラスです。
  2. Factory Method: Factory Methodパターンは、サブクラスが実装するファクトリメソッドを提供するインターフェースを定義します。これにより、クライアントは具体的なクラスを知ることなく、オブジェクトを生成できます。
  3. Abstract Factory: Abstract Factoryパターンは、関連するオブジェクトのファミリーを作成するためのインターフェースを提供します。このパターンは、異なるカテゴリの関連するオブジェクトを生成する場合に特に有用です。

なぜFactoryパターンが重要なのか?

  • 分離の原則: Factoryパターンは、オブジェクトの作成と使用を分離するので、システム内の異なる部分の依存関係を減らすことができます。
  • 柔軟性: Factoryパターンを使用すると、既存のコードを変更せずに新しいクラスタイプを簡単に追加できます。これは、プロダクトの拡張性にとって重要です。
  • コードの再利用: オブジェクトの生成ロジックを一箇所にまとめることで、コードを再利用しやすくなり、保守も容易になります。

Factoryパターンは、特にオブジェクトの生成が複雑であったり、生成されるオブジェクトのタイプが実行時に変わる可能性がある場合に、非常に役立ちます。

サンプルコード

ChatGPTが教えてくれたFactoryを使ったサンプル

package main

import (
	"fmt"
	"github.com/google/uuid"
	"errors"
)

// Carインターフェース
type Car interface {
	GetInfo() string
}

// VIN値オブジェクト
type VIN struct {
	value string
}

func NewVIN() VIN {
	return VIN{value: uuid.New().String()}
}

// Sedan構造体
type Sedan struct {
	VIN VIN
}

func (s Sedan) GetInfo() string {
	return fmt.Sprintf("This is a sedan car with VIN: %s", s.VIN.value)
}

// SUV構造体
type SUV struct {
	VIN VIN
}

func (s SUV) GetInfo() string {
	return fmt.Sprintf("This is an SUV with VIN: %s", s.VIN.value)
}

// CarFactory構造体
type CarFactory struct{}

func (cf CarFactory) CreateCar(carType string) (Car, error) {
	vin := NewVIN() // 車体番号をUUIDで生成

	if carType == "sedan" {
		// sedanの場合の複雑な初期化処理
		return Sedan{VIN: vin}, nil
	} else if carType == "suv" {
		// SUVの場合の複雑な初期化処理
		return SUV{VIN: vin}, nil
	} else {
		// サポートされていない車種の場合はエラーを返す
		return nil, errors.New("unsupported car type")
	}
}

func main() {
	factory := CarFactory{}

	// sedanの生成
	sedan, err := factory.CreateCar("sedan")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(sedan.GetInfo()) // 出力: This is a sedan car with VIN: {生成されたUUID}
	}

	// SUVの生成
	suv, err := factory.CreateCar("suv")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(suv.GetInfo()) // 出力: This is an SUV with VIN: {生成されたUUID}
	}
}

おまけ

面白く説明してって頼んだら。。。

🧙‍♂️**「カーマジックランド」へようこそ!**🚗✨

この不思議な土地では、大魔法使い「Factoryus Maximus」が車を魔法で作り出しています。彼は、「CarFactory」という強力な魔法の書を持っており、この書を使うことで様々なタイプの車を召喚することができます。

Carは、この世界に住む車の精霊たちです。彼らは皆、自分たちの情報を教えてくれる特別な能力GetInfoを持っています。

今日、Factoryus Maximusは、2つの車の精霊、「Sedan」🚘と「SUV」🚙を召喚することに決めました。

しかし、彼はただの車を召喚するだけではなく、それぞれの車にユニークな識別子「VIN」を持たせるという難易度の高い魔法を使います。この「VIN」は、車の精霊が一度召喚されたら変更することができない、非常に神秘的な文字列です。🔮

「VIN」はとても大切で、これを持つことで車の精霊は「Car Kingdom」で正式な市民として認められます。だから、Factoryus Maximusは「VIN」を新しい値オブジェクトとして作成し、これを車に付与します。

さて、Factoryus Maximusは、彼の魔法の書「CarFactory」を開き、「CreateCar」呪文を唱えます。📜✨

  1. 彼が「sedan」を呟くと、魔法の書は「Sedan」精霊を召喚し、ユニークな「VIN」を持たせます。この精霊は、自分自身がセダンの車であるという情報を教えてくれます。
  2. 次に彼が「suv」を呟くと、今度は「SUV」精霊が召喚され、同じようにユニークな「VIN」を持ちます。この精霊も自分自身がSUVの車であるという情報を教えてくれます。

しかし、Factoryus Maximusが「CarFactory」魔法の書で未知の言葉を呟くと、魔法の書は混乱してエラーメッセージを送り返します。これは「CarFactory」魔法の書がその言葉でどの車の精霊を召喚すれば良いかわからないためです。

さて、最終的にFactoryus Maximusは無事に2つの車の精霊を召喚しました。彼は彼らに「GetInfo」の能力を使って情報を教えてもらい、彼らが正しく召喚され、ユニークな「VIN」を持っていることを確認します。

これで、Factoryus Maximusは今日の魔法の冒険を終え、彼の「CarFactory」魔法の書を安全な場所にしまいます。そして、新しく召喚された車の精霊たちは「Car Kingdom」で新しい生活を始めるのです。

そして、どこか遠くで、プログラマーたちがこの魔法のようなコードを使って、現実世界で車を作成していることを、Factoryus Maximusは微笑みながら知っているのでした。


このお話は、プログラムが複雑なオブジェクトを作成する方法を示すものです。コードでは「CarFactory」構造体を使って、異なるタイプの車(SedanSUV)を作成し、それぞれにユニークな識別子(VIN)を割り当てています。これは実際のプログラミングでよく使われるパターンで、オブジェクトの作成を効率的に行うために使われます。