關於建造者模式,專業的術語介紹可以直接戳到菜鳥教程去學習——菜鳥教程~建造者模式
談談個人體會
建造者模式簡直就是爲全家桶系列而生的,它使用一個個簡單的對象進而構成複雜的對象,就像肯德基使用簡單的薯條、雞腿、雞翅、可樂等單一的食物推出了全家桶套餐。後序又將各種單一的產品進行組合他,不斷推出全新的套餐,拉動消費。
屁話不多說了,下面介紹下我學習建造者模式後,用C++描述的一個簡單demo。
UML圖
強推一波staruml,這軟件確實有丶東西,除了根據代碼反向生成UML圖不夠精準(當然也可以說是我寫的狗屁東西不符合人家的標準,狗頭.jpg),但是它對於一個對象的各種描述真的是相當到位了,對於上手UML圖絕對是利器。
飲料和漢堡是抽象類,各自派生出自己的產品,而它們和建造者又是聚合關係。離開了建造者它們也可以生活得很好。
代碼
builder_mode.h
#pragma once
#include <string>
using namespace std;
class hamburger
{
protected:
int m_price;
public:
virtual int show_price() = 0;
};
class chicken_hamburger:public hamburger
{
public:
//不能使用列表形式初始化從基類繼承的成員變量
chicken_hamburger(int price = 10)
{
m_price = price;
}
int show_price()
{
return m_price;
}
};
class beef_hamburger:public hamburger
{
public:
beef_hamburger(int price = 12)
{
m_price = price;
}
int show_price()
{
return m_price;
}
};
class drink
{
protected:
int m_price;
public:
virtual int show_price() = 0;
};
class cola:public drink
{
public:
cola(int price = 5)
{
m_price = price;
}
int show_price()
{
return m_price;
}
};
class juice:public drink
{
public:
juice(int price = 8)
{
m_price = price;
}
int show_price()
{
return m_price;
}
};
class builder
{
private:
hamburger *m_hamburger;
drink *m_drink;
int m_price;
string m_name;
public:
builder()
{
m_hamburger = NULL;
m_drink = NULL;
m_price = 0;
}
~builder()
{
if (m_hamburger != NULL)
{
delete m_hamburger;
m_hamburger = NULL;
}
if (m_drink != NULL)
{
delete m_drink;
m_drink = NULL;
}
}
void prepare_cola()
{
if (m_hamburger != NULL)
{
delete m_hamburger;
m_hamburger = NULL;
}
if (m_drink != NULL)
{
delete m_drink;
m_drink = NULL;
}
m_price = 0;
m_drink = new cola;
m_name = "cola";
}
void prepare_beef_hamburger()
{
if (m_hamburger != NULL)
{
delete m_hamburger;
m_hamburger = NULL;
}
if (m_drink != NULL)
{
delete m_drink;
m_drink = NULL;
}
m_price = 0;
m_hamburger = new beef_hamburger;
m_name = "beef_hamburger";
}
void prepare_beef_hamburger_with_cola()
{
if (m_hamburger != NULL)
{
delete m_hamburger;
m_hamburger = NULL;
}
if (m_drink != NULL)
{
delete m_drink;
m_drink = NULL;
}
m_price = 0;
m_hamburger = new beef_hamburger(10);
m_drink = new cola(3);
m_name = "beef_hamburger_with_cola";
}
void prepare_chicken_hamburger_with_juice()
{
if (m_hamburger != NULL)
{
delete m_hamburger;
m_hamburger = NULL;
}
if (m_drink != NULL)
{
delete m_drink;
m_drink = NULL;
}
m_price = 0;
m_hamburger = new chicken_hamburger(8);
m_drink = new juice(6);
m_name = "chicken_hamburger_with_juice";
}
int show_price()
{
if (m_drink != NULL)
m_price += m_drink->show_price();
if (m_hamburger != NULL)
m_price += m_hamburger->show_price();
return m_price;
}
string show_name()
{
return m_name;
}
};
builder_mode.cpp
#include <iostream>
#include "builder_mode.h"
using namespace std;
int main(int argc, char const *argv[])
{
builder buil;
buil.prepare_chicken_hamburger_with_juice();
cout << "name: " << buil.show_name() << endl;
cout << "price: " << buil.show_price() << "RMB" <<endl;
buil.prepare_cola();
cout << "name: " << buil.show_name() << endl;
cout << "price: " << buil.show_price() << "RMB" << endl;
return 0;
}
恭喜自己,寫demo的時候又踩坑了,真的是一踩一個準,一踩一個爽鴨!
切記,派生類不能使用列表形式初始化從基類繼承過來的成員變量
這是爲什麼呢?
結果
什麼時候我也可以擁有一個全家桶,裏面啥都有…
醒醒,明天該上班寫bug了