一. 建造者模式

建造者模式:将一个复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示

应用场景:

  1. 当你希望使用代码创建不同形式的产品(例如石头或木头房屋),即制造过程相似,且仅有细节上的差异。
  2. 构造组合树或其它复杂对象。建造者模式能让你分步骤构造产品,你甚至可以递归调用这些步骤,这在创建对象树时非常方便。

我们来模拟一个例子:组装玩具。我们来组装一辆小汽车,小汽车由轮子、车身、发动机构成

#include <cstdio>                                                                                                                                       
#include <memory>                                                                                                                                       

class CarBuilder{
public:
    virtual ~CarBuilder() = default;

protected:
    virtual void buildWheel(void) const = 0;
    virtual void buildBody(void) const = 0;
    virtual void buildEngine(void) const = 0;

public:
    virtual void build(void) const = 0;
};

class BMWbuild : public CarBuilder{
private:
    void buildWheel(void) const override{
        printf("Building BWM wheel...\n");
    }

    void buildBody(void) const override{
        printf("Building BWM car body...\n");
    }

    void buildEngine(void) const override{
        printf("Building BWM engine...\n");
    }                                                                                                                                          

public:
    void build(void) const override{
        this->buildWheel();
        this->buildBody();
        this->buildEngine();
        printf("BWM construcion completed.\n");
    }
};

class Benzbuild : public CarBuilder{
private:
    void buildWheel(void) const override{
        printf("Building Mercedes wheel...\n");
    }
    
    void buildBody(void) const override{
        printf("Building Mercedes car body...\n");
    }
    
    void buildEngine(void) const override{
        printf("Building Mercedes engine...\n");
    }

public:
    void build(void) const override{
        this->buildWheel();
        this->buildBody();
        this->buildEngine();
        printf("Mercedes construcion completed.\n");
    }
};

class CarDirector{
private:
    std::unique_ptr<CarBuilder> car_builder;    

public:
    CarDirector(std::unique_ptr<CarBuilder> &&car_builder)
    :car_builder(std::move(car_builder)){}

public:
    void setBuilder(std::unique_ptr<CarBuilder> &&car_builder){
        this->car_builder = std::move(car_builder);
    }

    void build(void) const{
        this->car_builder->build();     
    }
};

int main(void){
    CarDirector car_director(std::make_unique<Benzbuild>());
    car_director.build();

    printf("==========================\n");
    car_director.setBuilder(std::make_unique<BMWbuild>());
    car_director.build();
    return 0;
} 

二. 观察者模式

观察者模式:它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,是他们能够自动更新自己。

应用场景:

  1. 当一个对象状态的改变需要改变其它对象,或实际对象是事先未知的或动态变化时,可使用观察者模式。
  2. 当应用中的一些对象必须观察其它对象时,可使用该模式。但仅能在有限时间内或特定情况下使用。

我们来模拟一个例子:坐标的移动,W、A、S、D 分别是向上,向左,向下,向右移动

#include <cstdio>
#include <utility>
#include <string>
#include <vector>
#include <algorithm>

class ObKeyBoard{
public:
    virtual ~ObKeyBoard() = default;

public:
    virtual void update(const std::string &key) = 0;
};

class Character : public ObKeyBoard{
private:
    std::pair<int, int> position;

public:
    Character(const std::pair<int, int> &position)
    :position(position){}

public:
    void update(const std::string &key) override{
        if(key == "W")
            this->position.second += 1;
        else if(key == "S")
            this->position.second -= 1;
        else if(key == "A")
            this->position.first -= 1;
        else if(key == "D")
            this->position.first += 1;
    }

    void getPos(void) const{
        printf("(%d, %d)\n", this->position.first, this->position.second);
    }
};

class KeyBoard{
private:
    std::vector<ObKeyBoard *> ob_vector;
  
public:
    void addOb(ObKeyBoard *ob){
        this->delOb(ob);
        this->ob_vector.emplace_back(ob);
    }

    void delOb(ObKeyBoard *ob){
        this->ob_vector.erase(std::remove_if(this->ob_vector.begin(), this->ob_vector.end(), 
                    [ob](ObKeyBoard *observer){ return observer == ob; }), this->ob_vector.end());
    }

    void notify(const std::string &key) const{
        for(const auto &elem : this->ob_vector)
            elem->update(key);
    }

    void W(void) const{
        this->notify("W");
    }

    void A(void) const{
        this->notify("A");
    }

    void S(void) const{
        this->notify("S");
    }

    void D(void) const{
        this->notify("D");
    }
};

int main(void){
    Character character(std::make_pair(0, 0));
    KeyBoard keyboard;
    keyboard.addOb(&character);
    
    character.getPos();
    keyboard.A();
    keyboard.W();
    character.getPos();
    
    keyboard.delOb(&character);
    keyboard.A();
    keyboard.W();
    character.getPos();
    return 0;
} 

作业

利用牛顿迭代法求平方根