ホームページ >バックエンド開発 >Golang >Go デザイン パターン #Factory

Go デザイン パターン #Factory

Susan Sarandon
Susan Sarandonオリジナル
2024-10-12 06:11:02256ブラウズ

Go Design Patterns #Factory

ファクトリーメソッド

ファクトリー メソッドは、オブジェクトを作成するためのインターフェイスを提供する創造的なデザイン パターンですが、サブクラスが作成されるオブジェクトのタイプを変更できるようにします。 Factory メソッドは、new を使用してオブジェクトを直接インスタンス化するのではなく、オブジェクト作成の責任をサブクラスまたはメソッドに委任し、柔軟性とスケーラビリティを促進します。

問題提起

オブジェクトを作成する必要があるが、必要となるオブジェクトの正確なクラスが事前にわからない場合。アプリケーションは、共通の動作を共有するものの実装が異なるさまざまなタイプのオブジェクトを処理する必要があります。さらに、新しいタイプのオブジェクトが追加されるたび、またはオブジェクトの作成方法が変更されるたびにコードを変更することは避けたいと考えています。

解決できる具体的な問題

  • 複雑なオブジェクトの作成: クラスを直接インスタンス化すると、コードが特定の実装に結び付けられるため、コードが硬直化し、保守が困難になります。

  • 動的オブジェクトの作成: 多くの場合、必要なオブジェクトのタイプは実行時まで分からないため、この決定は柔軟である必要があります。

  • インスタンス化のカプセル化: オブジェクト作成ロジックはクライアント コードから分離する必要があるため、オブジェクトの作成方法の変更はシステムの残りの部分に影響を与えません。

  • スケーラビリティ: 新しいタイプの製品 (オブジェクト) を追加する必要がある場合、既存のコードの変更を回避できるスケーラブルなソリューションが必要です。

現実世界の例

自動車工場で車を注文すると、ユーザーの好み (例: 電気かガソリン) に応じて、工場が適切な車種を組み立てて提供してくれると想像してください。顧客は自動車の組み立ての具体的な詳細を知る必要はなく、製品を受け取るだけです。

実装

package main

import (
    "fmt"
    "os"
)

// Step 1: Define the Product Interface
type Car interface {
    Drive() string
    FuelType() string
}

// Step 2: Concrete Products (Electric Car and Gas Car)
type ElectricCar struct{}

func (e *ElectricCar) Drive() string {
    return "Driving an electric car"
}

func (e *ElectricCar) FuelType() string {
    return "Powered by electricity"
}

type GasCar struct{}

func (g *GasCar) Drive() string {
    return "Driving a gas-powered car"
}

func (g *GasCar) FuelType() string {
    return "Powered by gasoline"
}

// Step 3: Define the Factory Interface
type CarFactory interface {
    CreateCar(brand string) Car
}

type carFactory struct{}

func (carFactory *carFactory) CreateCar() Car {
    carPreference := os.Getenv("CAR_PREFERENCE")

    if carPreference == "electric" {
        return &ElectricCar{}
    }

    // here we just instantiate the struct, but you could also 
    // have another functions to help create the object if it's complex
    return &GasCar{}
}

// Step 4: Client Code
func main() {
    // Client uses the factory to create objects
    carFactory := carFactory{}

    // Creating a Gas Car
    gasCar := carFactory.CreateCar()
    fmt.Println(gasCar.Drive())    // Output: Driving a gas-powered car
    fmt.Println(gasCar.FuelType()) // Output: Powered by gasoline

    // Creating an Electric Car
    os.Setenv("CAR_PREFERENCE", "electric")
    electricCar := carFactory.CreateCar()
    fmt.Println(electricCar.Drive())    // Output: Driving an electric car
    fmt.Println(electricCar.FuelType()) // Output: Powered by electricity
}

製品インターフェイス: Drive() メソッドと FuelType() メソッドを使用して共通インターフェイス (Car) を定義します。

具体的な製品: 動作を定義する特定のクラス (ElectricCar、GasCar) とのインターフェイスを実装します。

ファクトリ インターフェイス: Car オブジェクトを作成するためのメソッド (CreateCar()) を指定します。

工場のロジック: 工場は、クライアントの好みに基づいてどのタイプの車を作成するかを決定します。ここでは環境変数を使用した例を示していますが、任意のロジックに基づくこともできます。

クライアント コード: 共通インターフェイスを通じて返されたオブジェクトを使用して、作成の詳細を知らずに工場に車両をリクエストします。

以上がGo デザイン パターン #Factoryの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。