3--设计模式:建造者模式

实现
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal。
3--设计模式:建造者模式

#pragma once
#include <QString>

class Packing {
public:
    Packing() {}
    virtual ~Packing() {}
    virtual QString packMethod() const = 0;
};

class Wrapper : public Packing {
public:
    ~Wrapper() {}
    QString packMethod() const { return "Packing: Wrapper"; }
};

class Bottle : public Packing {
public:
    ~Bottle() {}
    QString packMethod() const { return "Packing: Bottle"; }
};

#pragma once

#include <QString>
#include "Packing.h"

// Item:表示食物的条目,由汉堡和冷饮组成
// 汉堡:蔬菜\鸡肉汉堡(子类),通过纸盒包装(内部实例化纸盒包装);
//
class Item {
public:
    Item() {}
    virtual ~Item() {}

    virtual Packing* packing() const { return nullptr; }

    virtual QString name() const { return ""; }
    virtual float price() const { return 0.0f; }
};

/*****************汉堡**********************/
class Burger : public Item {
public:
    Burger() {}
    virtual ~Burger() {}

    Packing* packing() const { return new Wrapper; }

    //    virtual QString name() const = 0;
    //    virtual float price() const = 0;
};

class VegBurger : public Burger {
public:
    VegBurger() {}
    virtual ~VegBurger() {}

    QString name() const { return "Veg Burger"; }
    float price() const { return 15.0f; }
};

class ChickenBurger : public Burger {
public:
    ChickenBurger() {}
    virtual ~ChickenBurger() {}

    QString name() const { return "Chicken Burger"; }
    float price() const { return 25.0f; }
};

/******************冷饮*********************/
class ColdDrink : public Item {
public:
    ColdDrink() {}
    virtual ~ColdDrink() {}

    Packing* packing() const { return new Bottle; }

    //    virtual QString name() const = 0;
    //    virtual float price() const = 0;
};

class Coke : public ColdDrink {
public:
    Coke() {}
    virtual ~Coke() {}

    QString name() const { return "Coke"; }
    float price() const { return 10.0f; }
};

class Pepsi : public ColdDrink {
public:
    Pepsi() {}
    virtual ~Pepsi() {}

    QString name() const { return "Pepsi"; }
    float price() const { return 20.0f; }
};

#pragma once

#include <Item.h>
#include <QDebug>
#include <QList>

class Meal {
public:
    Meal() { _items.clear(); };
    ~Meal() {
        for (auto item : _items) {
            delete item;
            item = nullptr;
        }
    }

    void addItem(Item* item) { _items.push_back(item); }

    float getCost() {
        float cost = 0.0f;
        for (const auto& item : _items)
            cost += item->price();

        return cost;
    }
    void showItems() {
        for (const auto& item : _items) {
            qDebug().noquote() << QStringLiteral("Item: %1").arg(item->name());
            qDebug().noquote() << QStringLiteral("Packing: %1").arg(item->packing()->packMethod());
            qDebug().noquote() << QStringLiteral("Price: %1").arg(item->price());
        }
    }

private:
    QList<Item*> _items;
};

对于菜单创建类,感觉是写死的,应该可以更灵活的组合。

#pragma once
#include "Meal.h"
class MealBuilder {
public:
    MealBuilder(){};

    Meal prepareVegMeal() {
        Meal meal;
        meal.addItem(new VegBurger);
        meal.addItem(new Coke);

        return meal;
    }

    Meal prepareNonVegMeal() {
        Meal meal;
        meal.addItem(new ChickenBurger);
        meal.addItem(new Pepsi);

        return meal;
    }
};

#include <QCoreApplication>

#include "MealBuilder.h"

int main() {
    MealBuilder mealBuilder;

    Meal vegMeal = mealBuilder.prepareVegMeal();
    qDebug() << "Veg Meal";
    vegMeal.showItems();
    qDebug() << QStringLiteral("Total Cost: %1").arg(vegMeal.getCost());
    qDebug().noquote() << "**************************************";

    Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
    qDebug() << "Non-Veg Meal";
    nonVegMeal.showItems();
    qDebug() << QStringLiteral("Total Cost: %1").arg(nonVegMeal.getCost());
}

上一篇:CMU15-213学习笔记(五)virtual memory虚拟内存


下一篇:c# – 如何创建在线signalR服务器