设计模式(五)——建造者模式

三、建造者模式实例

1、快餐套餐实例

    快餐套餐一般含有主食、饮料、点心三部分组成,KFC快餐套餐Mcdonald快餐套餐的生成过程大致都是一样的。每份套餐由主食、饮料、点心三部分组成,当每部分具体的食品可能不同,如主食可能是鸡肉卷、汉堡等,即对象的各组成部分可能因为需求的变化面临剧烈的变化。

    MealBuilder快餐套餐的生产步骤的抽象接口

        KFCMealBuilderKFC快餐套餐的具体生产步骤

        McDonalMealBuilderMcdonalds快餐套餐的具体生产步骤

    Waiter服务员控制快餐套餐的生产过程

    Meal:快餐套餐的基本属性

wKioL1nQmeSQsZMpAADBm205EPQ215.jpg

Meal产品信息类:
#ifndef MEAL_H
#define MEAL_H
#include <iostream>
#include <string>
using namespace std;
 
class Meal
{
public:
    void setFood(const string& food)
    {
        m_food = food;
        cout << "add a "<< food << endl;
    }
    void setDrink(const string& drink)
    {
        m_drink = drink;
        cout << "add a "<< drink << endl;
    }
    void setNosh(const string& nosh)
    {
        m_nosh = nosh;
        cout << "add a "<< nosh << endl;
    }
private:
    string m_food;
    string m_drink;
    string m_nosh;
};
 
#endif // MEAL_H
MealBuilder抽象建造者:
#ifndef MEALBUILDER_H
#define MEALBUILDER_H
#include "Meal.h"
 
class MealBuilder
{
public:
    virtual void buildFood() = 0;
    virtual void buildDrink() = 0;
    virtual void buildNosh() = 0;
    virtual Meal* getMeal() = 0;
};
 
#endif // MEALBUILDER_H
KFCMealBuilder具体建造者:
#ifndef KFCMEALBUILDER_H
#define KFCMEALBUILDER_H
#include <string>
#include <iostream>
#include "MealBuilder.h"
using namespace std;
 
class KFCMealBuilder : public MealBuilder
{
public:
    KFCMealBuilder()
    {
        m_meal = new Meal();
        cout << "KFC FastFood is ready..." << endl;
    }
    virtual void buildFood()
    {
        m_meal->setFood("Dragon Twister");
    }
    virtual void buildDrink()
    {
        m_meal->setDrink("Coca-Cola");
    }
    virtual void buildNosh()
    {
        m_meal->setNosh("Popcorn chicken");
    }
    virtual Meal* getMeal()
    {
        return m_meal;
    }
private:
    Meal* m_meal;
};
 
#endif // KFCMEALBUILDER_H
McDonalMealBuilder具体建造者:
#ifndef MCDONALMEALBUILDER_H
#define MCDONALMEALBUILDER_H
#include "MealBuilder.h"
 
class McDonalMealBuilder : public MealBuilder
{
public:
    McDonalMealBuilder()
    {
        m_meal = new Meal();
        cout << "McDonal FastFood is ready..." << endl;
    }
    virtual void buildFood()
    {
        m_meal->setFood("hamburger");
    }
    virtual void buildDrink()
    {
        m_meal->setDrink("Coca-Cola");
    }
 
    virtual void buildNosh()
    {
        m_meal->setDrink("Chips");
    }
    virtual Meal* getMeal()
    {
        return m_meal;
    }
private:
    Meal* m_meal;
};
 
#endif // MCDONALMEALBUILDER_H
指挥者Waiter类:
#ifndef WAITER_H
#define WAITER_H
#include <string>
#include <iostream>
#include "MealBuilder.h"
using namespace std;
 
class Waiter
{
public:
    Waiter(MealBuilder* builder)
    {
        m_builder = builder;
    }
    void createMeal()
    {
        m_builder->buildFood();
        m_builder->buildDrink();
        m_builder->buildNosh();
        cout << "Fast Food is done." << endl;
    }
private:
    MealBuilder* m_builder;
};
 
#endif // WAITER_H
客户端调用程序:
#include "Waiter.h"
#include "KFCMealBuilder.h"
#include "McDonalMealBuilder.h"
 
int main()
{
    Waiter McDonalWaiter(new McDonalMealBuilder());
    McDonalWaiter.createMeal();
 
    Waiter KFCWaiter(new KFCMealBuilder());
    KFCWaiter.createMeal();
    return 0;
}


2、不同岗位工资实例

    公司员工工资的计算一般是:底薪+奖金-税金研发人员底薪分为一级8000、二级6000、三级4000三个等级,销售人员的底薪则统一为3000,奖金则由经理根据业绩考核发放。税金则根据奖金和底薪的数额进行计算。由此看出工资的计算方式是比较稳定的构建算法,但对工资的每一部分都会根据不同的情况产生不同的算法,如何将客户端与变化剧烈的底薪、奖金和税金计算方式分离,比较适合用建造者模式。

wKiom1nQmlSjZAz8AAENxAWEdC0151.jpg

Income产品:
#ifndef INCOME_H
#define INCOME_H
 
//产品
class Income
{
public:
    Income()
    {}
    //研发人员底薪设置接口
    void setBasicSalary(char type)
    {
        if(type == 'A')
            m_basicSalary = 4000;
        else if(type == 'B')
            m_basicSalary = 6000;
        else if(type == 'C')
            m_basicSalary = 8000;
    }
    //销售人员底薪社会子接口
    void setBasicSalary(unsigned int basic)
    {
        m_basicSalary = basic;
    }
    unsigned int getBasicSalary()
    {
        return m_basicSalary;
    }
    void setBonus(double bonus)
    {
        m_bonus = bonus;
    }
    unsigned int getBonus()
    {
        return m_bonus;
    }
    unsigned int getIncomeTax()
    {
        //税金根据底薪和奖金总额确定税率
        unsigned total = m_basicSalary + m_bonus;
        if(total < 10000)
            m_incomeTax = total * 0.1;
        else
            m_incomeTax = total * 0.15;
        return m_incomeTax;
    }
private:
    unsigned int m_basicSalary;//底薪
    unsigned int m_bonus;//奖金
    unsigned int m_incomeTax;//税金
};
 
#endif // INCOME_H
Post抽象建造者:
#ifndef POST_H
#define POST_H
 
//Builder抽象类
class Post
{
public:
    virtual double buildBasicSalary() = 0;
    virtual double buildBonus() = 0;
    virtual double buildIncomeTax() = 0;
    virtual void setBonus(double bonus) = 0;
};
 
#endif // POST_H
Developer具体建造者:
#ifndef DEVELOPER_H
#define DEVELOPER_H
#include "Income.h"
#include "Post.h"
 
//具体Builder
class Developer : public Post
{
public:
    Developer(char level)//分为三个等级
    {
        m_income = new Income();
        m_income->setBasicSalary(level);
    }
    virtual double buildBasicSalary()
    {
        double basic = 0;
        basic = m_income->getBasicSalary();
        return basic;
    }
    virtual double buildBonus()
    {
        double number = 0;
        number = m_income->getBonus();
        return number;
    }
    void setBonus(double bonus)
    {
        m_income->setBonus(bonus);
    }
    virtual double buildIncomeTax()
    {
        double n = 0;
        n = m_income->getIncomeTax();
        return n;
    }
private:
    Income* m_income;
};
 
#endif // DEVELOPER_H
SalesMan具体建造者:
#ifndef SALESMAN_H
#define SALESMAN_H
#include "Post.h"
#include "Income.h"
 
//具体Builder
class SalesMan : public Post
{
public:
    SalesMan()//销售人员无等级
    {
        m_income = new Income();
        m_income->setBasicSalary(3000u);
    }
    double buildBasicSalary()
    {
        double basic = 0;
        basic = m_income->getBasicSalary();
        return basic;
    }
    double buildBonus()
    {
        double number = 0;
        number = m_income->getBonus();
        return number;
    }
    void setBonus(double bonus)
    {
        m_income->setBonus(bonus);
    }
    double buildIncomeTax()
    {
        double n = 0;
        n = m_income->getIncomeTax();
        return n;
    }
private:
    Income* m_income;
};
 
#endif // SALESMAN_H
Accountant指挥者类:
#ifndef ACCOUNTANT_H
#define ACCOUNTANT_H
#include "Post.h"
#include <iostream>
using namespace std;
 
//Director指挥者类
class Accountant
{
public:
    //财务,指定要具体计算谁的薪水
    Accountant(Post* post)
    {
        m_post = post;
    }
    double computeSalary()//计算薪水
    {
        double basic = m_post->buildBasicSalary();
        double bonus = m_post->buildBonus();
        double tax = m_post->buildIncomeTax();
        double income = basic + bonus - tax;
        cout << "Salary: " << income<< endl;
        return income;
    }
private:
    Post* m_post;
};
 
#endif // ACCOUNTANT_H
 
Manager管理者类:
#ifndef MANAGER_H
#define MANAGER_H
#include "Post.h"
 
//辅助类,负责考核员工的业绩并确定发放的奖金数额
class Manager
{
public:
    Manager(Post* post)
    {
        m_post = post;
    }
    //根据业绩确定员工的奖金数额
    void setBonus(double bonus)
    {
        m_post->setBonus(bonus);
    }
private:
    Post* m_post;
};
 
#endif // MANAGER_H
客户调用程序:
#include <iostream>
#include "Manager.h"
#include "Accountant.h"
#include "Developer.h"
#include "SalesMan.h"
 
using namespace std;
 
int main()
{
    Developer developer1('C');
    Manager manager1(&developer1);
    manager1.setBonus(5000);
    Accountant* accountant1 = new Accountant(&developer1);
    accountant1->computeSalary();
 
    Developer developer2('A');
    Manager manager2(&developer2);
    manager2.setBonus(3000);
    Accountant* accountant2 = new Accountant(&developer2);
    accountant2->computeSalary();
 
    SalesMan sale;
    Manager manager3(&sale);
    manager3.setBonus(12000);
    Accountant* accountant3 = new Accountant(&sale);
    accountant3->computeSalary();
 
    delete accountant1,accountant2,accountant3;
 
    return 0;
}