设计模式与XML(二)建造者模式和单例模式(C++)

一、实验目的及要求

1、掌握创建型模式的概念。

2、掌握工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式的构造方式及使用情景。

 

二、实验设备(环境)

1、   软件需求: Dev-Cpp5.4, Rational Rose / Microsoft Visio

2、   硬件需求: Pentium III 450以上的CPU处理器,1G以上的内存,2G的*硬盘空间

 

三、实验内容

1、建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。用建造者模式实现KFC的2份套餐(A套餐和B套餐),并在客户端(main函数)打印套餐的内容。

 

2、假设步骤1中的KFC订餐系统中的机器人服务员只能有一个实例,请用单例模式改造这个机器人服务员的角色。

四、实验步骤与结果

练习三

1.建造者模式KFC设计结构图:

设计模式与XML(二)建造者模式和单例模式(C++)

 

2.程序运行结果:

设计模式与XML(二)建造者模式和单例模式(C++)

 

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.运行结果:

设计模式与XML(二)建造者模式和单例模式(C++)

 

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;
}