设计模式学习

创见型模式

参考:设计模式

工厂方法模式

父类提供个创建对象的接口,子类会根据情况来决定实例化什么类型;
解耦产品的代码和实际的创建代码,这样新增产品的时候,新增一个类 && 创建者的子类即可。

#include <iostream>

class Product {
public:
    Product() { std::cout << "base Product call" << std::endl; }
    virtual ~Product() {}
    virtual void Operation() const = 0;
};

class ProductA : public Product {
public:
    ProductA() {std::cout << "ProductA creat." << std::endl;}
    ~ProductA() {}
    void Operation() const override {
        std::cout << "Opearate A" << std::endl;
    }
};

class ProductB : public Product {
public:
    ProductB() {std::cout << "ProductB creat." << std::endl;}
    ~ProductB() {}
    void Operation() const override {
        std::cout << "Opearate B" << std::endl;
    }
};


class Creator {
public:
    Creator() { std::cout << "base Creator" << std::endl;}
    virtual ~Creator() {}
    virtual Product* FactoryMethod() const = 0;
    void SomeOpreation() const {
        Product* product = this->FactoryMethod();
        product->Operation();
        delete product;
    };
};


class CreatorA : public Creator {
public:
    CreatorA() { std::cout << "Create A " << std::endl;}
    ~CreatorA() {}
    Product* FactoryMethod () const override {
        return new ProductA;
    }
};

class CreatorB : public Creator {
public:
    CreatorB() { std::cout << "Create B " << std::endl;}
    ~CreatorB() {}
    Product* FactoryMethod () const override {
        return new ProductB;
    }
};

void FactoryClient(const Creator& creator) {
    std::cout << "Opreation of Creator" << std::endl;
    creator.SomeOpreation();
}


void testFactoryV2() {
    Creator* creator = new CreatorA();
    FactoryClient(*creator);
    std::cout << " ------ " << std::endl;
    Creator* creatorB = new CreatorB();
    FactoryClient(*creatorB);
    delete creator;
    delete creatorB;
}

抽象工厂模式

如果是产品的影响因素有两个维度,比如下图:
在这里插入图片描述
这种情况下,实际上每一层就是一个工厂方法。对于多层的整合,又可以用一个工厂,所以抽象工厂,实际上是工厂的工厂;

#include <iostream>

class Sofa {
public:
    virtual ~Sofa() {};
    virtual void RecordPrice() const = 0;
};

class MordernSofa : public Sofa {
public:
    void RecordPrice() const override {
        std::cout << " gagagaga, sofa: $100" << std::endl;
    }
};

class TraditionalSofa : public Sofa {
public:
    void RecordPrice() const override {
        std::cout << " This is traditional sofa: $1." << std::endl;
    }
};

class Chair {
public:
    virtual ~Chair() {};
    virtual void RecordPrice() const = 0;
};

class MordernChair: public Chair {
public:
    void RecordPrice() const override {
        std::cout << " gagagaga, chair: $50." << std::endl;
    }
};

class TraditionalChair : public Chair {
public:
    void RecordPrice() const override {
        std::cout << " This is traditional chair: $1." << std::endl;
    }
};

class AbstractFactory {
public:
    virtual Sofa* CreateSofa() const = 0;
    virtual Chair* CreateChair() const = 0;
};


class MordernFactory : public AbstractFactory {
public:
    Sofa* CreateSofa() const override {
        return new MordernSofa();
    }
    Chair* CreateChair() const override {
        return new MordernChair();
    }
};

class TraditionalFactory : public AbstractFactory {
public:
    Sofa* CreateSofa() const override {
        return new TraditionalSofa();
    }
    Chair* CreateChair() const override {
        return new TraditionalChair();
    }
};

void AbstractFactoryClient(const AbstractFactory& factory) {
    const Sofa* sofa = factory.CreateSofa();
    const Chair* chair = factory.CreateChair();
    sofa->RecordPrice();
    chair->RecordPrice();
    delete sofa;
    delete chair;
}

void testAbstractFactory() {
    MordernFactory* modern = new MordernFactory();
    AbstractFactoryClient(*modern);
    delete modern;
    TraditionalFactory* traditional = new TraditionalFactory();
    AbstractFactoryClient(*traditional);
    delete traditional;
}

生成器模式

将构建一个对象的复杂过程打散掉,然后一步一步构建复杂的对象。
使用场景点:

  1. 当构建一个对象的过程很复杂,但对用户来说,只是要最后的成品;
  2. 如果多个成品之间构造只有部分不同,其他大部分相同,这样也可以用builer模式来创建,这也是把复杂产品构建过程打散的主要原因;
    builder的模式主要参考的就是造汽车,把轮子,引擎等部分拆解,然后组装起来。甚至提供个方法造摩托车也很方便。
    配合着下面例子里的director,这个可以尽可能复用代码,组装相似的产品也十分方便。这样封装给用户的更加完整。
#include <iostream>
#include <vector>


class Engine {
public:
    virtual ~Engine() {}
    virtual void SetUp() const = 0;
    virtual std::string GetName() const = 0;
};

class BikeEngine : public Engine {
public:
    void SetUp() const override {
        std::cout << "Use your feet." << std::endl;
    }
    std::string GetName() const override {
        std::cout << "Bike Engine" << std::endl;
        return "Bike Engine";
    }
};


class CarEngine : public Engine {
public:
    void SetUp() const override {
        std::cout << "Eng, eng ,,,,," << std::endl;
    }
    std::string GetName() const override {
        std::cout << "Car Engine" << std::endl;
        return "Car Engine";
    }
};

class Divice {
public:
    std::vector<std::string> parts_;
    void ListAllParts() {
        for (int i = 0; i < parts_.size(); i ++) {
            if (i == parts_.size() - 1) {
                std::cout << parts_[i] << std::endl;
            } else {
                std::cout << parts_[i] << ", ";
            }
        }
    }
};

class Builder {
public:
    virtual ~Builder() {}
    virtual void ProduceEngine(Engine* engine) const = 0;
    virtual void ProduceWheels(int number) const = 0;
};


class BuilderA : public Builder {
private:
    Divice* device;
public:
    void reset() {
        this->device = new Divice();
    }

    BuilderA() {
        this->reset();
    }

    ~BuilderA() {
        delete device;
    }

    void ProduceEngine (Engine* engine) const override {
        engine->SetUp();
        this->device->parts_.push_back(engine->GetName());
    }

    void ProduceWheels (int number) const override {
        std::cout << "wheels number: " << number << std::endl;
    }

    Divice* GetProduct() {
        Divice* result= this->device;
        this->reset();
        return result;
    }

};

class Director {
private:
    Builder* builder;
public:
    void setBuilder(Builder* builder) {
        this->builder = builder;
    }

    void BuildSuperBike(){
        Engine* engine = new CarEngine;
        this->builder->ProduceEngine(engine);
        this->builder->ProduceWheels(2);
    }

    void BuildNormalBike(){
        Engine* engine = new BikeEngine;
        this->builder->ProduceEngine(engine);
        this->builder->ProduceWheels(2);
    }

    void BuildNormalCar(){
        Engine* engine = new CarEngine;
        this->builder->ProduceEngine(engine);
        this->builder->ProduceWheels(4);
    }
};

void testGenerator() {
    Director* director= new Director();
    BuilderA* builderA = new BuilderA();
    director->setBuilder(builderA);

    director->BuildNormalBike();
    Divice* p1 = builderA->GetProduct();
    p1->ListAllParts();
    delete p1;

    director->BuildNormalCar();
    Divice* p2 = builderA->GetProduct();
    p2->ListAllParts();
    delete p2;
}

原型模式

用来避免多次初始化对象,尤其是当初始化过程中还有一些相似的操作,初始化过程又繁琐,又耗时,都用同样的数据来搞,最终每个实例的不同只是基于这些相同的初始化基础上改一些东西;
原型模式,提供一个clone的方法,避免每次都重复走初始化一个对象的过程;

#include <iostream>
#include <unordered_map>


enum TYPE {
    PROTOTYPE_1 = 0,
    PROTOTYPE_2 = 1
};

class Prototype {
protected:
    std::string name_;
    float prototype_field_;
public:
    Prototype() {}
    Prototype(std::string name) : name_(name) {}
    virtual ~Prototype() {}
    virtual Prototype* clone() const = 0;
    virtual void Method(float prototype_field) {
        this->prototype_field_ = prototype_field;
        std::cout << "Call Method from " << name_ << " with field : " << prototype_field << std::endl;
    }
};

class Prototype1 : public Prototype {
private:
    float prototype_field_;
public:
    Prototype1(std::string name, float field) : Prototype(name), prototype_field_(field){}
    Prototype* clone () const override {
        return new Prototype1(*this);
    }
};

class Prototype2 : public Prototype {
private:
    float prototype_field_;
public:
    Prototype2(std::string name, float field) : Prototype(name), prototype_field_(field){}
    Prototype* clone () const override {
        return new Prototype2(*this);
    }
};

class ProtoFactory {
private:
    std::unordered_map<TYPE, Prototype*> record;
public:
    ProtoFactory() {
        record[TYPE::PROTOTYPE_1] = new Prototype1("PROTOTYPE_1 ", 50.f);
        record[TYPE::PROTOTYPE_2] = new Prototype2("PROTOTYPE_2 ", 50.f);
    }

    Prototype* create(TYPE type) {
        return this->record[type]->clone();
    }

    ~ProtoFactory() {
        delete record[TYPE::PROTOTYPE_1];
        delete record[TYPE::PROTOTYPE_2];
    }

};

void prototypeClient(ProtoFactory &prototype_factory) {
    std::cout << "Let's create a Prototype 1\n";

    Prototype *prototype = prototype_factory.create(TYPE::PROTOTYPE_1);
    prototype->Method(90);
    delete prototype;

    std::cout << "\n";

    std::cout << "Let's create a Prototype 2 \n";

    prototype = prototype_factory.create(TYPE::PROTOTYPE_2);
    prototype->Method(10);

    delete prototype;
}

单例模式

如果有个东西,全局只希望是有一个,只能他来读写某些东西或者只能他来操作什么东西,那么全局就只能有一个实例。这时候用单例模式。

  1. 构造函数变成private,别人都别想用;
  2. 提供个全局都能用的函数,getInstance,用static修饰,全局就一个,判断下不空就直接给,空的话,创建一个给出去。
#include <iostream>
#include <thread>


class Singleton {
private:
    static Singleton* pinstance_;
    static std::mutex mutex_;

protected:
    std::string value_;
    Singleton(const std::string value) : value_(value) {}
    ~Singleton() {}

public:
    // 不能复制构造
    Singleton(Singleton& other) = delete;
    // 不能直接赋值
    void operator=(const Singleton&) = delete;

    static Singleton* getInstance(const std::string& value);
    std::string value() {
        return value_;
    }
    void otherMethod() {}
};


Singleton* Singleton::pinstance_ = nullptr;
std::mutex Singleton::mutex_;

Singleton* Singleton::getInstance(const std::string &value) {
    std::lock_guard<std::mutex> lock(mutex_);
    if (pinstance_ == nullptr) {
        pinstance_ = new Singleton(value);
    }
    return pinstance_;
}


void threadFoo() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("FOO");
    std::cout << singleton->value() << std::endl;
}

void threadBar() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("BAR");
    std::cout << singleton->value() << std::endl;
}

void testSingleton() {
    std::thread t1(threadFoo);
    std::thread t2(threadBar);
    t1.join();
    t2.join();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值