C++におけるファクトリーメソッドと抽象ファクトリーの実装戦略

オブジェクト指向設計において、生成型デザインパターンはシステムの柔軟性を高める重要な手法です。特にファクトリーメソッドパターンと抽象ファクトリーパターンは、オブジェクト生成のカプセル化を通じて依存関係を解消し、拡張性を確保するための有効なアプローチです。

ファクトリーメソッドパターンの再考

このパターンでは、基底クラスがオブジェクト生成のインタフェースを定義し、実際のインスタンス化をサブクラスに委譲します。重要なのは、生成ロジックをクライアントコードから分離することで、新しい製品タイプの追加が既存コードの変更なしに可能になる点です。

実装時に注意すべき点として、不適切な適用による過剰な抽象化があります。生成ロジックに多様性がない場合や、製品階層が単純なケースでは、パターンの導入が逆に保守性を低下させる可能性があります。特に、新規製品追加時に工場クラス自体を変更する必要がある場合は、開閉原則の違反となるため、依存関係の逆転原則を適用した設計が求められます。

#include <memory>
#include <iostream>

// 製品の基底インタフェース
class Component {
public:
    virtual void execute() const = 0;
    virtual ~Component() = default;
};

// 具体的製品A
class StandardComponent : public Component {
public:
    void execute() const override {
        std::cout << "標準コンポーネントの実行" << std::endl;
    }
};

// 具体的製品B
class CustomComponent : public Component {
public:
    void execute() const override {
        std::cout << "カスタムコンポーネントの実行" << std::endl;
    }
};

// 工場の基底クラス
class ComponentFactory {
public:
    virtual std::unique_ptr<Component> create() const = 0;
    virtual ~ComponentFactory() = default;
};

// 標準コンポーネント工場
class StandardFactory : public ComponentFactory {
public:
    std::unique_ptr<Component> create() const override {
        return std::make_unique<StandardComponent>();
    }
};

// カスタムコンポーネント工場
class CustomFactory : public ComponentFactory {
public:
    std::unique_ptr<Component> create() const override {
        return std::make_unique<CustomComponent>();
    }
};

int main() {
    std::unique_ptr<ComponentFactory> factory = std::make_unique<StandardFactory>();
    auto component = factory->create();
    component->execute();
}

抽象ファクトリーパターンの応用

複数の関連製品を一括生成する必要がある場合に有効なのが抽象ファクトリーパターンです。このパターンでは、製品ファミリーを生成するためのインタフェースを定義し、一貫した製品セットの作成を可能にします。特に、テーマやプラットフォームごとに異なるUIコンポーネントを提供するシステムで有効です。

設計上の落とし穴として、製品間の関連性が薄い場合の過剰抽象化が挙げられます。製品ファミリーの拡張時に既存コードを変更せずに済むよう、インタフェース設計に十分な考慮が必要です。また、実行時に製品ファミリーを切り替える必要がある場合は、ファクトリーのインスタンス管理戦略を事前に策定すべきです。

#include <memory>
#include <iostream>

// メインコンポーネント階層
class PrimaryElement {
public:
    virtual void activate() const = 0;
    virtual ~PrimaryElement() = default;
};

class CoreElement : public PrimaryElement {
public:
    void activate() const override {
        std::cout << "コア要素のアクティブ化" << std::endl;
    }
};

class EnhancedElement : public PrimaryElement {
public:
    void activate() const override {
        std::cout << "拡張要素のアクティブ化" << std::endl;
    }
};

// 補助コンポーネント階層
class AuxiliaryElement {
public:
    virtual void configure() const = 0;
    virtual ~AuxiliaryElement() = default;
};

class BasicAuxiliary : public AuxiliaryElement {
public:
    void configure() const override {
        std::cout << "基本補助要素の設定" << std::endl;
    }
};

class AdvancedAuxiliary : public AuxiliaryElement {
public:
    void configure() const override {
        std::cout << "高度補助要素の設定" << std::endl;
    }
};

// 抽象ファクトリー
class SystemFactory {
public:
    virtual std::unique_ptr<PrimaryElement> createPrimary() const = 0;
    virtual std::unique_ptr<AuxiliaryElement> createAuxiliary() const = 0;
    virtual ~SystemFactory() = default;
};

// 基本システムファクトリー
class BasicFactory : public SystemFactory {
public:
    std::unique_ptr<PrimaryElement> createPrimary() const override {
        return std::make_unique<CoreElement>();
    }
    
    std::unique_ptr<AuxiliaryElement> createAuxiliary() const override {
        return std::make_unique<BasicAuxiliary>();
    }
};

// 高度システムファクトリー
class AdvancedFactory : public SystemFactory {
public:
    std::unique_ptr<PrimaryElement> createPrimary() const override {
        return std::make_unique<EnhancedElement>();
    }
    
    std::unique_ptr<AuxiliaryElement> createAuxiliary() const override {
        return std::make_unique<AdvancedAuxiliary>();
    }
};

int main() {
    std::unique_ptr<SystemFactory> factory = std::make_unique<BasicFactory>();
    auto primary = factory->createPrimary();
    auto auxiliary = factory->createAuxiliary();
    
    primary->activate();
    auxiliary->configure();
}

タグ: C++ FactoryPattern AbstractFactoryPattern CreationalPatterns

5月29日 17:49 投稿