C++的工厂模式与建造者模式连用

发布于:2024-06-26 ⋅ 阅读:(13) ⋅ 点赞:(0)

工厂模式与建造者模式连用

工厂模式

工厂模式:是一种常用的设计模式,它属于创建型设计模式,旨在将对象的创建过程与使用过程分离,以实现解耦和灵活性。工厂模式通过提供一个公共的接口来创建对象,而不直接使用new操作符,从而降低了系统的耦合度,使得代码更加易于维护和扩展。

工厂模式可以分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。简单工厂模式由一个工厂类根据传入的参数动态决定创建哪一个产品类的实例。工厂方法模式则定义了一个创建对象的接口,由子类决定实例化哪一个类。抽象工厂模式则更为复杂,它允许生产一系列相关或独立的产品,而不需要关心具体产品的创建过程。

工厂模式的优点包括:
降低了耦合度,使得调用者只需要关心产品的接口,而不必了解具体的实现细节。
提高了扩展性,当需要增加新的产品时,只需要扩展相应的工厂类或具体产品类,而不需要修改已有的代码。屏蔽了产品的具体实现,使得系统更加灵活和可维护。
工厂模式也存在一些缺点:
当需要增加新的产品时,可能需要增加相应的具体类和对象来实现工厂逻辑,这可能会增加系统的复杂度。
在某些情况下,使用工厂模式可能会引入额外的类和对象,增加了系统的开销。
适用场景:
当一个对象拥有很多子类时,可以使用工厂模式来创建对象,避免直接使用new操作符。
当创建某个对象时需要进行许多额外的操作时,工厂模式可以隐藏这些操作,使得客户端代码更加简洁。
当系统后期需要经常扩展时,工厂模式可以将对象实例化的任务交给实现类完成,提高系统的可扩展性。

首先定义抽象工厂接口和具体工厂类。抽象工厂用于创建不同类型的汽车组件

// 汽车组件接口
class Engine {
public:
    virtual std::string getType() const = 0;
    virtual ~Engine() = default;
};

class Wheel {
public:
    virtual std::string getType() const = 0;
    virtual ~Wheel() = default;
};

// 具体的汽车组件
class SUVEngine : public Engine {
public:
    std::string getType() const override {
        return "SUV Engine";
    }
};

class SedanEngine : public Engine {
public:
    std::string getType() const override {
        return "Sedan Engine";
    }
};

class SUVTire : public Wheel {
public:
    std::string getType() const override {
        return "SUV Tire";
    }
};

class SedanTire : public Wheel {
public:
    std::string getType() const override {
        return "Sedan Tire";
    }
};

// 抽象工厂接口
class CarFactory {
public:
    virtual std::unique_ptr<Engine> createEngine() const = 0;
    virtual std::unique_ptr<Wheel> createWheel() const = 0;
    virtual ~CarFactory() = default;
};

// 具体工厂:SUV工厂
class SUVFactory : public CarFactory {
public:
    std::unique_ptr<Engine> createEngine() const override {
        return std::make_unique<SUVEngine>();
    }

    std::unique_ptr<Wheel> createWheel() const override {
        return std::make_unique<SUVTire>();
    }
};

// 具体工厂:Sedan工厂
class SedanFactory : public CarFactory {
public:
    std::unique_ptr<Engine> createEngine() const override {
        return std::make_unique<SedanEngine>();
    }

    std::unique_ptr<Wheel> createWheel() const override {
        return std::make_unique<SedanTire>();
    }
};

建造者模式

建造者模式 (Builder Pattern) 属于创建型模式的一种, 主要用于将一个复杂对象的构建与它的表示分离, 向用户屏蔽复杂对象组成部分的创建细节。
在者模式中,有4个角色:
建造者(Builder):为创建一个产品对象的各个部件指定抽象接口。

具体建造者(ConcreteBuilder):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。

指挥者(Director):指挥并构造一个使用Builder接口的对象,负责和客户(Client)对话。

产品(Product):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

模式优点

  1. 用户只需要指定要建造的类型就可以得到它们,而具体的建造过程和细节不需要知道。
  2. 建造代码与表示相分离,如果要改变一个产品的内部表示,只要再定义一个新的具体的建造者就可以了。
  3. 建造过程由指挥者来控制,建造细节由一个抽象类来控制,对于实现建造细节的具体类来说,不会遗漏某一个步骤。

模式缺点

  1. 产品必须有共同点,范围有限制。
  2. 如内部变化复杂,会有很多的建造类

示意代码如下

// 产品类:汽车
class Car {
public:
    void setEngine(std::unique_ptr<Engine> eng) {
        engine = std::move(eng);
    }

    void setWheel(std::unique_ptr<Wheel> whl) {
        wheel = std::move(whl);
    }

    void show() const {
        if (engine) {
            std::cout << "Engine: " << engine->getType() << std::endl;
        }
        if (wheel) {
            std::cout << "Wheel: " << wheel->getType() << std::endl;
        }
    }

private:
    std::unique_ptr<Engine> engine;
    std::unique_ptr<Wheel> wheel;
};

// 建造者接口
class CarBuilder {
public:
    virtual void buildEngine() = 0;
    virtual void buildWheel() = 0;
    virtual std::unique_ptr<Car> getCar() = 0;
    virtual ~CarBuilder() = default;
};

// 具体建造者
class ConcreteCarBuilder : public CarBuilder {
public:
    ConcreteCarBuilder(const CarFactory& factory) : factory(factory), car(std::make_unique<Car>()) {}

    void buildEngine() override {
        car->setEngine(factory.createEngine());
    }

    void buildWheel() override {
        car->setWheel(factory.createWheel());
    }

    std::unique_ptr<Car> getCar() override {
        return std::move(car);
    }

private:
    const CarFactory& factory;
    std::unique_ptr<Car> car;
};
// 指导者类
class Director {
public:
    void setBuilder(CarBuilder* bldr) {
        builder = bldr;
    }

    void construct() {
        if (builder) {
            builder->buildEngine();
            builder->buildWheel();
        }
    }

private:
    CarBuilder* builder = nullptr;
};

具体使用

int main() {
    // 创建具体的工厂
    SUVFactory suvFactory;
    SedanFactory sedanFactory;

    // 创建具体的建造者
    ConcreteCarBuilder suvBuilder(suvFactory);
    ConcreteCarBuilder sedanBuilder(sedanFactory);

    // 指导者
    Director director;

    // 构建SUV
    director.setBuilder(&suvBuilder);
    director.construct();
    std::unique_ptr<Car> suv = suvBuilder.getCar();
    std::cout << "Built a new SUV:\n";
    suv->show();

    // 构建Sedan
    director.setBuilder(&sedanBuilder);
    director.construct();
    std::unique_ptr<Car> sedan = sedanBuilder.getCar();
    std::cout << "Built a new Sedan:\n";
    sedan->show();

    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到