C++ デザイン パターン - 知識の復習の概要

シンプルな工場パターン

単純なファクトリ パターン関連クラスを作成して使用する手順は次のとおりです。

(1) 新しいクラスを作成します。これをファクトリ クラスと呼びます。単純なファクトリ パターンの場合、必要なファクトリ クラスは 1 つだけです。

(2) このファクトリ クラスにパブリック メンバー関数を追加し、この関数を使用して必要なオブジェクトを作成します (一般にファクトリ関数と呼ばれるこの関数)。

(3) 使い方としては、まずファクトリクラスのオブジェクトを作成し、このオブジェクトを通じてファクトリ関数を呼び出すことで、指定した型のインスタンスオブジェクトを生成することができます。


#include<iostream>
#include<memory>
using namespace std;

class Animal
{
public:
    virtual void sound(){};
};

class Dog : public Animal
{
public:
    void sound()override
    {
        cout<<"汪汪"<<endl;
    }  
};

class Cat : public Animal
{
public:
    void sound()override
    {
        cout<<"喵喵"<<endl;
    }
};

enum class Type{DOG,CAT};

class Animalfactory
{
public:
    Animalfactory(){};
    ~Animalfactory(){};
    Animal * ptr = nullptr;
    Animal* createAnimal(Type type)
    {
        switch (type)
        {
        case Type::DOG:
            ptr = new Dog;
            break;

        case Type::CAT:
            ptr = new Cat;
            break;
        }
        
        return ptr;
    }
};

int main()
{
    Animalfactory * fac = new Animalfactory();
    std::shared_ptr<Animal> p = std::shared_ptr<Animal>(fac->createAnimal(Type::DOG));
    
    p->sound();
    return 0;
}

 抽象的な工場パターン

抽象ファクトリ パターンは、より複雑で変化しやすいビジネス シナリオに適しています。一般的に、同じ機能を持つが属性を変更する一連のコンポーネントに、その後の拡張が非常に便利になるように抽象クラスを追加し、それを組み合わせます。ファクトリークラス 必要なオブジェクトを作成できます。


抽象的なファクトリ パターンは開閉の原則に従いますが、ファクトリ パターンはそうではありません。

ファクトリ パターンによって作成されたオブジェクトに対応するクラスは、抽象クラスを提供する必要はありません [このプロダクト クラス コンポーネントには可変要素はありません] 抽象ファクトリ パターンによって作成されたオブジェクトに対応するクラスには、抽象基本クラスがあります [この製品クラス コンポーネントには可変要素はありません
]はこの製品クラスのコンポーネントの変動要因です]

次のコードは自動車製造を例としており、電気自動車と燃料自動車を製造する必要があり、2 つの自動車には異なるエンジン タイプが必要であると想定しています。したがって、電気自動車工場と燃料自動車工場を作成する必要があり、この 2 つの自動車工場クラスがガス田工場の基本クラスとなります。

#include <iostream>
#include <memory>

// 抽象产品:汽车零部件
class CarPart {
public:
    virtual ~CarPart() {}
    virtual void start() const = 0;
};

// 具体产品:电动汽车电机
class ElectricCarMotor : public CarPart {
public:
    void start() const override {
        std::cout << "Electric car motor started." << std::endl;
    }
};

// 具体产品:燃油汽车发动机
class GasolineEngine : public CarPart {
public:
    void start() const override {
        std::cout << "Gasoline engine started." << std::endl;
    }
};

// 抽象工厂:汽车工厂
class CarFactory {
public:
    virtual ~CarFactory() {}
    virtual std::unique_ptr<CarPart> createCarPart() const = 0;
};

// 具体工厂:电动汽车工厂
class ElectricCarFactory : public CarFactory {
public:
    std::unique_ptr<CarPart> createCarPart() const override {
        return std::make_unique<ElectricCarMotor>();
    }
};

// 具体工厂:燃油汽车工厂
class GasolineCarFactory : public CarFactory {
public:
    std::unique_ptr<CarPart> createCarPart() const override {
        return std::make_unique<GasolineEngine>();
    }
};

int main() {
    // 使用电动汽车工厂创建一个电动汽车
    std::unique_ptr<CarFactory> electricCarFactory = std::make_unique<ElectricCarFactory>();
    std::unique_ptr<CarPart> carPart = electricCarFactory->createCarPart();
    carPart->start(); // 输出:Electric car motor started.

    // 使用燃油汽车工厂创建一个燃油汽车
    std::unique_ptr<CarFactory> gasolineCarFactory = std::make_unique<GasolineCarFactory>();
    carPart = gasolineCarFactory->createCarPart();
    carPart->start(); // 输出:Gasoline engine started.

    return 0;
}

アダプターモード

アダプター パターンは、クラスのインターフェイスをクライアントが期待する別のインターフェイスに変換する構造的な設計パターンです。アダプターを使用すると、互換性のないクラスが連携して動作できるようになります。

アダプター パターンには次の役割が含まれます。

  1. ターゲット インターフェイス (Target): クライアントが予期するインターフェイス、つまりクライアントが使用する必要があるインターフェイス。

  2. ソースインターフェース (Adapte): 適応する必要があるインターフェース、つまり、元々クライアントのニーズを満たしていないインターフェース。

  3. アダプター: ソース インターフェイスをターゲット インターフェイスに変換するクラス。

アダプター パターンの一般的なアプリケーション シナリオは次のとおりです。

  1. 既存のクラスを使用していて、そのインターフェイスが要件を満たしていないことが判明した場合は、アダプター パターンを使用して、そのインターフェイスをクライアントが期待するインターフェイスに変換できます。

  2. 開発プロセス中に、アダプター パターンを使用して、さまざまなインターフェイスやフレームワークと互換性を持たせることができます。

簡単に言うと、クラスのインターフェースをユーザーが望む別のインターフェースに変換し、互換性のないオブジェクト同士が連携して動作できるようにするモードで、このモードをアダプターモードと呼びます。

#include<iostream>
#include<string>
#include<memory>
using namespace std;

//目标接口
class MedioPlayer
{
public:
    virtual void play(string filename) = 0;
};


//源接口
class Vedio
{
public:
    virtual void play(string filename) = 0;
};

class Mp4 : public Vedio
{
public:
    void play(string filename)
    {
        std::cout<<"play mp4 file"<<std::endl;
    }
};

class Vlc : public Vedio
{
public:
    void play(string filename)
    {
        std::cout<<"play Vlc"<<std::endl;
    }
};

//适配器
class MedioPlayerApapter : public MedioPlayer
{
public:
    MedioPlayerApapter(Vedio *v):vedio(v){}
    ~MedioPlayerApapter(){}
    void play(string filename) override
    {
        if (filename.find(".mp4") != std::string::npos) vedio->play(filename);
        else if (filename.find(".vlc") != std::string::npos) vedio->play(filename);
        else std::cout<<"Invalid vedio"<<std::endl;
    }

    void setVedio(Vedio *v)
    {
        vedio = v;
    }

private:
    Vedio *vedio;
};

int main()
{
    std::shared_ptr<Vedio> mp4 = std::make_shared<Mp4>();
    std::shared_ptr<Vedio> vlc = std::make_shared<Vlc>();


    std::shared_ptr<MedioPlayerApapter> p = std::make_shared<MedioPlayerApapter>(mp4.get());
    p->play("xx.mp4");

    p->setVedio(vlc.get());
    p->play("xx.vlc");

}

 後で、より一般的なデザイン パターンが使用され、更新されます。

おすすめ

転載: blog.csdn.net/weixin_40582034/article/details/131570919