天天看點

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

大話設計模式8—建造者模式(建造小人)

  • 1.需求:建造小人
  • 2.普通實作
  • 3.建造者模式實作
  • 4.建造者模式

1.需求:建造小人

假設需要使用畫筆和圖檔畫兩個小人,小人隻需要包含頭部、身體和腿就可以。這兩個小人一個是瘦人、一個是胖子。現給出畫筆和圖檔兩個類如下:

class Pen {
public:
	Pen();
};

class Graphics {
public:
	Graphics();
};
           

構造函數

Pen::Pen() {
	cout << "use yellow pen" << endl;
}

Graphics::Graphics() {
	cout << "start to write" << endl;
}
           

main函數

int main()
{
	Pen *p = new Pen();
	Graphics *g = new Graphics();
	//自己添加
	return 0;
}
           

請設計BuildThinPerson和BuildFatPerson兩個類完成最終需要輸出如下。

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

2.普通實作

設計兩個類BuildThinPerson 和BuildFatPerson,這兩個類十分相似,都有兩個成員變量m_pen和m_graphics指針,來自題設給定的Pen和Graphics 兩個類,BuildThinPerson的方法就是畫頭、身子、腿如下。

class BuildThinPerson {
public:
	BuildThinPerson(Pen *pen, Graphics *graphics);
	void BuildHead();
	void BuildBody();
	void BuildLeg();
	void BuildThin();
private:
	Pen *m_pen;
	Graphics *m_graphics;
};
           

BuildThinPerson 類的實作很簡單,由于main函數已經實作了一部分,是以BuildThinPerson 類的構造函數傳參即可。在BuildHead(); BuildBody();BuildLeg()三個函數中列印需要的輸出,而BuildThin()函數負責調用三個函數封裝起來。

BuildThinPerson::BuildThinPerson(Pen * pen, Graphics * graphics) :m_pen(pen), m_graphics(graphics) {
}

void BuildThinPerson::BuildHead() {
	cout << "build Head of thin person" << endl;
}

void BuildThinPerson::BuildBody() {
	cout << "build Body of thin person" << endl;
}

void BuildThinPerson::BuildLeg() {
	cout << "build Leg of thin person" << endl;
}

void BuildThinPerson::BuildThin()
{
	BuildHead();
	BuildBody();
	BuildLeg();
}
           

BuildFatPerson類的實作隻有列印語句和BuildThinPerson不同略去實作。那麼補全的main函數如下

int main()
{
	Pen *p = new Pen();
	Graphics *g = new Graphics();

	BuildThinPerson *thin_person = new BuildThinPerson(p, g);
	thin_person->BuildThin();
	
	BuildFatPerson *fat_person = new BuildFatPerson(p, g);
	fat_person->BuildFat();
	return 0;
}
           

達到建造兩個小人的要求

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

3.建造者模式實作

檢視上述代碼,可以發現兩個類BuildThinPerson 和BuildFatPerson相似度很高,是以第一步,我們考慮把共同的東西放到新設計的父類PersonBuilder中,BuildThinPerson 和BuildFatPerson繼承他,三類如下:

class PersonBuilder {
protected:
	Pen *m_pen;
	Graphics *m_graphics;
public:
	PersonBuilder(Pen *pen,Graphics *graphics);
	virtual ~PersonBuilder() {};
	virtual void BuildHead() {};
	virtual void BuildBody() {};
	virtual void BuildLeg() {};
};

class BuildThinPerson:public PersonBuilder{
public:
	BuildThinPerson(Pen *pen, Graphics *graphics);
	virtual void BuildHead();
	virtual void BuildBody();
	virtual void BuildLeg();
};

class BuildFatPerson:public PersonBuilder {
public:
	BuildFatPerson(Pen *pen, Graphics *graphics);
	virtual void BuildHead();
	virtual void BuildBody();
	virtual void BuildLeg();
};
           

這三個類實作也很簡單,子類重寫父類的BuildHead(); BuildBody();BuildLeg()函數。

PersonBuilder::PersonBuilder(Pen* pen, Graphics* graphics) : m_pen(pen), m_graphics(graphics) {
}

BuildThinPerson::BuildThinPerson(Pen* pen, Graphics* graphics): PersonBuilder(pen,graphics){
}

void BuildThinPerson::BuildHead() {
	cout << "build Head of thin person" << endl;
}

void BuildThinPerson::BuildBody() {
	cout << "build Body of thin person" << endl;
}

void BuildThinPerson::BuildLeg() {
	cout << "build Leg of thin person" << endl;
}

BuildFatPerson::BuildFatPerson(Pen * pen, Graphics * graphics) :PersonBuilder(pen, graphics){
}

void BuildFatPerson::BuildHead() {
	cout << "build Head of fat person" << endl;
}

void BuildFatPerson::BuildBody() {
	cout << "build Body of fat person" << endl;
}

void BuildFatPerson::BuildLeg() {
	cout << "build Leg of fat person" << endl;
}
           

重點來了,用戶端調用時還是需要知道建造頭、身子、腿的方法,我們想要隔絕使用者和建造過程的關聯,不讓使用者知道建造的過程和細節。是以我們還需要一個指揮者的類來控制建造過程。

指揮者PersonDirector 類管理抽象建造者類的指針,通過調用CreatPerson進行建造。

class PersonDirector {
private:
	PersonBuilder* m_person_builder;
public:
	PersonDirector(PersonBuilder* person_builder);
	void CreatPerson();
};
           

PersonDirector類實作,構造函數通過使用者告訴指揮者需要建造什麼小人,而CreatPerson調用建造過程就行

PersonDirector::PersonDirector(PersonBuilder * person_builder):m_person_builder(person_builder){
}

void PersonDirector::CreatPerson()
{
	m_person_builder->BuildHead();
	m_person_builder->BuildBody();
	m_person_builder->BuildLeg();
}
           

以上完成了所有類的實作,各類之間關系如下

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

main函數就很好寫出來了,隻需要向指揮者傳入想建立的小人就行

int main()
{
	Pen *p = new Pen;
	Graphics *g = new Graphics;
	
	PersonBuilder *build1 = new BuildThinPerson(p,g);
	PersonDirector *dir = new PersonDirector(build1);
	dir->CreatPerson();

	PersonBuilder *build2 = new BuildFatPerson(p, g);
	dir = new PersonDirector(build2);
	dir->CreatPerson();

	delete p;
	delete g;
	delete build1;
	delete dir;
	return 0;
}
           

完成題設要求

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

所有代碼如下:

build.h

#ifndef BUILD_H
#define BUILD_H
class Pen {
public:
	Pen();
};

class Graphics {
public:
	Graphics();
};

class PersonBuilder {
protected:
	Pen *m_pen;
	Graphics *m_graphics;
public:
	PersonBuilder(Pen *pen,Graphics *graphics);
	virtual ~PersonBuilder() {};
	virtual void BuildHead() {};
	virtual void BuildBody() {};
	virtual void BuildLeg() {};
};

class BuildThinPerson:public PersonBuilder{
public:
	BuildThinPerson(Pen *pen, Graphics *graphics);
	virtual void BuildHead();
	virtual void BuildBody();
	virtual void BuildLeg();
};

class BuildFatPerson:public PersonBuilder {
public:
	BuildFatPerson(Pen *pen, Graphics *graphics);
	virtual void BuildHead();
	virtual void BuildBody();
	virtual void BuildLeg();
};

class PersonDirector {
private:
	PersonBuilder* m_person_builder;
public:
	PersonDirector(PersonBuilder* person_builder);
	void CreatPerson();
};

#endif

           

build.cpp

#include"build.h"
#include<iostream>
using namespace std;
Pen::Pen(){
	cout << "use yellow pen" << endl;
}

Graphics::Graphics(){
	cout << "start to write" << endl;
}

PersonBuilder::PersonBuilder(Pen* pen, Graphics* graphics) : m_pen(pen), m_graphics(graphics) {

}

BuildThinPerson::BuildThinPerson(Pen* pen, Graphics* graphics): PersonBuilder(pen,graphics){
}


void BuildThinPerson::BuildHead() {
	cout << "build Head of thin person" << endl;
}

void BuildThinPerson::BuildBody() {
	cout << "build Body of thin person" << endl;
}

void BuildThinPerson::BuildLeg() {
	cout << "build Leg of thin person" << endl;
}


BuildFatPerson::BuildFatPerson(Pen * pen, Graphics * graphics) :PersonBuilder(pen, graphics){
}

void BuildFatPerson::BuildHead() {
	cout << "build Head of fat person" << endl;
}

void BuildFatPerson::BuildBody() {
	cout << "build Body of fat person" << endl;
}

void BuildFatPerson::BuildLeg() {
	cout << "build Leg of fat person" << endl;
}

PersonDirector::PersonDirector(PersonBuilder * person_builder):m_person_builder(person_builder){
}

void PersonDirector::CreatPerson()
{
	m_person_builder->BuildHead();
	m_person_builder->BuildBody();
	m_person_builder->BuildLeg();
}

           

main.cpp

#include"build.h"

int main()
{
	Pen *p = new Pen;
	Graphics *g = new Graphics;
	PersonBuilder *build1 = new BuildThinPerson(p,g);
	PersonDirector *dir = new PersonDirector(build1);
	dir->CreatPerson();

	PersonBuilder *build2 = new BuildFatPerson(p, g);
	dir = new PersonDirector(build2);
	dir->CreatPerson();

	delete p;
	delete g;
	delete build1;
	delete dir;
	return 0;
}
           

4.建造者模式

建造者模式:将一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。使用者隻需要指定需要建造的類型就可以的得到他們,而具體的建構過程和細節不需要知道。

如下圖所示,Builder是建立小人的抽象類,具體建造者繼承他進行構造和裝配。

大話設計模式8—建造者模式(建造小人)1.需求:建造小人2.普通實作3.建造者模式實作4.建造者模式

建造者模式主要用于建立一些複雜對象,這些對象内部構造間的順序通常是穩定的,但對象内部的構造通常面臨複雜變化。

繼續閱讀