設計模式與XML(二)建造者模式和單例模式(C++)
一、實驗目的及要求
1、掌握建立型模式的概念。
2、掌握工廠模式、抽象工廠模式、單例模式、建造者模式、原型模式的構造方式及使用情景。
二、實驗裝置(環境)
1、 軟體需求: Dev-Cpp5.4, Rational Rose / Microsoft Visio
2、 硬體需求: Pentium III 450以上的CPU處理器,1G以上的記憶體,2G的自由硬碟空間
三、實驗內容
1、建造者模式可以用於描述KFC如何建立套餐:套餐是一個複雜物件,它一般包含主食(如漢堡、雞肉卷等)和飲料(如果汁、可樂等)等組成部分,不同的套餐有不同的組成部分,而KFC的服務員可以根據顧客的要求,一步一步裝配這些組成部分,構造一份完整的套餐,然後返回給顧客。用建造者模式
2、假設步驟1中的KFC訂餐系統中的機器人服務員只能有一個例項,請用單例模式改造這個機器人服務員的角色。
四、實驗步驟與結果
練習三
1.建造者模式KFC設計結構圖:
2.程式執行結果:
3.程式碼分析:
Builder.cpp
抽象Builder基類,定義不同部分的建立介面,ConcreteBuilder1與ConcreteBuilder2是Builder的兩個派生類,用於實現兩種不同的建造細節,使用Builder構建產品,構建產品的過程都一致,但是不同的builder有不同的實現。
程式碼:
#include "Builder.h" #include "Product.h" #include <iostream> using namespace std; //抽象Builder基類,定義不同部分的建立介面 Builder::Builder() { } Builder::~Builder() { } ConcreteBuilder1::ConcreteBuilder1() { product = new Product(); } ConcreteBuilder1::~ConcreteBuilder1() { } ConcreteBuilder2::ConcreteBuilder2() { product = new Product(); } ConcreteBuilder2::~ConcreteBuilder2() { } void ConcreteBuilder1::BuildPartA(const string& buildPara) { cout<<"套餐A1:"<<"一個漢堡"<<endl; product->SetPartA("一個漢堡"); } void ConcreteBuilder1::BuildPartB(const string& buildPara) { cout<<"套餐A2:"<<"一包薯條"<<endl; product->SetPartB("一包薯條"); } void ConcreteBuilder1::BuildPartC(const string& buildPara) { cout<<"套餐A3:"<<"一杯可樂"<<endl; product->SetPartC("一杯可樂"); } Product* ConcreteBuilder1::GetProduct() { return product; } void ConcreteBuilder2::BuildPartA(const string& buildPara) { cout<<"套餐B1:"<<"一個雞肉卷"<<endl; product->SetPartA("一個雞肉卷"); } void ConcreteBuilder2::BuildPartB(const string& buildPara) { cout<<"套餐B2:"<<"一盒土豆泥"<<endl; product->SetPartB("一盒土豆泥"); } void ConcreteBuilder2::BuildPartC(const string& buildPara) { cout<<"套餐B3:"<<"一杯果汁"<<endl; product->SetPartC("一杯果汁"); } Product* ConcreteBuilder2::GetProduct() { return product; } //ConcreteBuilder1與ConcreteBuilder2是Builder的兩個派生類,用於實現兩種不同的建造細節 // 使用Builder構建產品,構建產品的過程都一致,但是不同的builder有不同的實現
Builder.h
具體Builder的派生類,實現BuilderPartA和BuilderPartB和BuildPartC介面函式。
程式碼:
//Builder.h
#ifndef _BUILDER_H_
#define _BUILDER_H_
#include <string>
using namespace std;
class Product;
class Builder
{
public:
virtual ~Builder();
virtual void BuildPartA(const string& buildPara) = 0;
virtual void BuildPartB(const string& buildPara) = 0;
virtual void BuildPartC(const string& buildPara) = 0;
virtual Product* GetProduct() = 0;
//virtual Product* GetProduct() = 0;
protected:
Builder();
private:
};
// Builder的派生類,實現BuilderPartA和BuilderPartB和BuildPartC介面函式
class ConcreteBuilder1:public Builder
{
public:
ConcreteBuilder1();
~ConcreteBuilder1();
void BuildPartA(const string& buildPara);
void BuildPartB(const string& buildPara);
void BuildPartC(const string& buildPara);
Product* GetProduct();
//Product* GetProduct();
protected:
private:
Product *product;
//Product *product;
};
// Builder的派生類,實現BuilderPartA和BuilderPartB和BuildPartC介面函式
class ConcreteBuilder2:public Builder
{
public:
ConcreteBuilder2();
~ConcreteBuilder2();
void BuildPartA(const string& buildPara);
void BuildPartB(const string& buildPara);
void BuildPartC(const string& buildPara);
Product* GetProduct();
//Product* GetProduct();
protected:
private:
Product *product;
// Product *product;
};
#endif //~_BUILDER_H_
Director.cpp
引用Director類的product實現兩種Construct()和Construct1()的方法,輸出其中的內容。
程式碼:
#include "Director.h"
#include "Builder.h"
Director::Director(Builder* bld)
{
_bld = bld;
}
Director::~Director()
{
}
Product* Director::Construct()
{
_bld->BuildPartA("");
_bld->BuildPartB("");
_bld->BuildPartC("");
return _bld->GetProduct();
}
Director.h
定義Director類。
程式碼:
#ifndef _DIRECTOR_H_
#define _DIRECTOR_H_
class Product;
class Builder;
class Director
{
public:
Director(Builder* bld);
~Director();
Product * Construct();
protected:
private:
Builder* _bld;
};
#endif //~_DIRECTOR_H_
//Construct函式定義一個物件的整個構建過程,不同的部分之間的裝配方式都是一致的,
//首先構建PartA其次是PartB,只是根據不同的構建者會有不同的表示
Product.cpp
定義Product的set和get方法。
程式碼:
#include "Product.h"
Product::Product(){
}
Product::~Product(){
}
void Product::SetPartA(string pa)
{PartA=pa;}
void Product::SetPartB(string pb)
{PartB=pb;}
void Product::SetPartC(string pc)
{PartC=pc;}
string Product::GetPartA() const
{return PartA;}
string Product::GetPartB() const
{return PartB;}
string Product::GetPartC() const
{return PartC;}
Product.h
定義Product類。
程式碼:
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <string>
using namespace std;
class Product
{
public:
Product();
~Product();
void SetPartA(string pa);
void SetPartB(string pb);
void SetPartC(string pc);
string GetPartA() const ;
string GetPartB() const ;
string GetPartC() const ;
protected:
private:
string PartA;
string PartB;
string PartC;
};
#endif
main.cpp
定義Director的物件d1實現ConcreteBuilder1的Construct(),物件d2實現ConcreteBuilder2的Construct1()。
程式碼:
#include "Builder.h"
#include "Product.h"
#include "Director.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Director* d1 = new Director(new ConcreteBuilder1());
d1->Construct();
Director* d2 = new Director(new ConcreteBuilder2());
d2->Construct();
return 0;
}
練習四
1.單例模式設計結構圖:
2.執行結果:
3.程式碼分析:
與練習三相比,單例模式修改的程式碼有:
Director.cpp
程式碼:
#include "Director.h"
#include "Builder.h"
#include <iostream>
using namespace std;
Director* Director::_instance = 0;
Director::Director()
{
cout<<"KFC Director...."<<endl;
}
Director::Director(Builder* bld)
{
_bld = bld;
}
Director* Director::Instance()
{
if (_instance == 0)
{
_instance = new Director();
}
return _instance;
}
Product* Director::Construct(Builder* bld)
{
_bld=bld;
_bld->BuildPartA("");
_bld->BuildPartB("");
_bld->BuildPartC("");
return _bld->GetProduct();
}
Director.h
程式碼:
#ifndef _DIRECTOR_H_
#define _DIRECTOR_H_
#include <iostream>
using namespace std;
class Product;
class Builder;
class Director
{
public:
static Director* Instance();
Director(Builder* bld);
~Director();
Product * Construct();
Product * Construct(Builder* bld);
protected:
Director();
private:
static Director* _instance;
Builder* _bld;
};
#endif //~_DIRECTOR_H_
//Construct函式定義一個物件的整個構建過程,不同的部分之間的裝配方式都是一致的,
//首先構建PartA其次是PartB,只是根據不同的構建者會有不同的表示
main.cpp
程式碼:
#include "Builder.h"
#include "Product.h"
#include "Director.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Director* d1 = Director::Instance();
d1->Construct(new ConcreteBuilder1());
d1->Construct(new ConcreteBuilder2());
return 0;
}