通过例子学设计模式之--建造者模式以及使用场景说明(C++实现)

          相信我们基本都买过台式电脑吧。我们应该不会去买主板,CPU,内存等等子部件回家,然后自己组装成台式机。当然,也不排除某些发烧友这样做。但是对于多数人来说,我们只需要对老板说,我需要一台联想的或者惠普的电脑,老板组装好给我们就OK了。我们买车也是这样的,只是买一台车回家,而不是买回一堆的发动机等等零件。
           上面的例子,抽象一下,就是建造者模式。
           建造者模式是创建模式中最复杂的,这个复杂指的是类的结构和实现会复杂一些。它的使用场景不复杂,很好理解。就是创建复杂对象。什么是复杂对象呢,比如对象里面包含很多子部件,或者创建过程中每个子部件的创建顺序需要严格遵守。这时候,对于类的设计者就要封装这些复杂性,为类的使用者提供简便的接口即可,而不用理会对象是何创建的。
            很多人包括我自己也问,这个场景使用工厂方法模式可以吗?答案是可以,但是这样一来工厂方法里面的接口就需要处理很多事情,包括new多个子组件,控制创建的顺序。而使用建造者模式则会优美很多。这个反映了设计模式的使用原则,那就是"合适的才是最好的"。
           至于类图,网络上很多,这里就偷懒不画了,通过代码和例子来学习。通过调试学习下代码,看看类图,改改代码,才能更好理解模式。

           首先是测试结果:

           

           然后是完整C++代码:

           

/*  产品类,这里用"电脑类"来说明 */
class Computer
{
public:
	virtual void SetCPU() = 0; //CPU
	virtual void SetRAM() = 0; //内存
	virtual void SetDisk() = 0; //硬盘
	virtual void SetCDROM() = 0; 

	virtual void Run() = 0;

	virtual int GetRAMCount(){return m_CountOfRAM;}
	virtual int GetDiskCount(){return m_CountOfDisk;}
protected:
	int m_CountOfRAM; //内存条数量
	int m_CountOfDisk; //硬盘数量
};

class IBMComputer : public Computer
{
public:
	IBMComputer(int RAMCount,int DiskCount)
	{
		m_CountOfDisk = DiskCount;
		m_CountOfRAM = RAMCount;
	}
	virtual void SetCPU()
	{
		printf("IBMComputer::SetCPU...\r\n");
	}
	virtual void SetRAM()
	{
		printf("IBMComputer::SetRAM...\r\n");
	}
	virtual void SetDisk()
	{
		printf("IBMComputer::SetDisk...\r\n");
	}
	virtual void SetCDROM()
	{
		printf("IBMComputer::SetCDROM...\r\n");
	}

	virtual void Run()
	{
		printf("IBMComputer::Runing...\r\n");
	}
};

class LenovoComputer : public Computer
{
public:
	LenovoComputer(int RAMCount,int DiskCount)
	{
		m_CountOfDisk = DiskCount;
		m_CountOfRAM = RAMCount;
	}
	virtual void SetCPU()
	{
		printf("LenovoComputer::SetCPU...\r\n");
	}
	virtual void SetRAM()
	{
		printf("LenovoComputer::SetRAM...\r\n");
	}
	virtual void SetDisk()
	{
		printf("LenovoComputer::SetDisk...\r\n");
	}
	virtual void SetCDROM()
	{
		printf("LenovoComputer::SetCDROM...\r\n");
	}

	virtual void Run()
	{
		printf("LenovoComputer::Runing...\r\n");
	}
};

class Builder
{
public:
	virtual void BuildCPU() = 0;
	virtual void BuildRAM() = 0;
	virtual void BuildDisk() = 0;
	virtual void BuildCDROM() = 0;
	virtual Computer* GetComputer() = 0;

	virtual ~Builder()
	{
		if(m_pComputer)
		{
			delete []m_pComputer;
			m_pComputer = NULL;
		}
	}

protected:
	Computer* m_pComputer;
};

class IBMBuiler : public Builder
{
public:

	IBMBuiler()
	{
		m_pComputer = new IBMComputer(2,1);
		printf("IBM 电脑,需要2个内存条,1个硬盘\r\n");
	}

	virtual void BuildCPU()
	{
		m_pComputer->SetCPU();
	}
	virtual void BuildRAM()
	{
		m_pComputer->SetRAM();
	}
	virtual void BuildDisk()
	{
		m_pComputer->SetDisk();
	}
	virtual void BuildCDROM()
	{
		m_pComputer->SetCDROM();
	}

	virtual Computer* GetComputer()
	{
		return m_pComputer;
	}
};

class LenovoBuilder : public Builder
{
public:
	LenovoBuilder()
	{
		m_pComputer = new LenovoComputer(1,2);
		printf("Lenovo 电脑,需要1个内存条,2个硬盘\r\n");
	}
	virtual void BuildCPU()
	{
		m_pComputer->SetCPU();
	}
	virtual void BuildRAM()
	{
		m_pComputer->SetRAM();
	}
	virtual void BuildDisk()
	{
		m_pComputer->SetDisk();
	}
	virtual void BuildCDROM()
	{
		m_pComputer->SetCDROM();
	}

	virtual Computer* GetComputer()
	{
		return m_pComputer;
	}
};

class Director
{
public:
	Director(Builder* pBuilder)
	{
		m_pBuilder = pBuilder;
	}
	void BuildComputer()
	{
		m_pBuilder->BuildCPU();
		for(int i=0;i<m_pBuilder->GetComputer()->GetRAMCount();i++)
		{
			m_pBuilder->BuildRAM();
		}
		for(int i=0;i<m_pBuilder->GetComputer()->GetDiskCount();i++)
		{
			m_pBuilder->BuildDisk();
		}
		m_pBuilder->BuildCDROM();
	}
private:
	Builder* m_pBuilder;
};


void TestBuilder()
{
	Builder* b1 = new IBMBuiler();
	Director* director1 = new Director(b1);
	director1->BuildComputer();
	b1->GetComputer()->Run();


	Builder* b2 = new LenovoBuilder();
	Director* director2 = new Director(b2);

	director2->BuildComputer();
	b2->GetComputer()->Run();

	delete b1;
	delete b2;
	delete director1;
	delete director2;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值