设计模式 ---- 生成器模式
理解生成器模式
在工厂3种模式理解种,使用了猫吃鱼理解
那么生成器是解决什么问题的呢,这里可以理解为,猫要怎样吃鱼(当然,这和工厂方法中的猫吃鱼,并无必然联系)
例如,猫要吃一条鱼,鱼头怎么吃:清蒸,鱼尾真么吃:红烧,鱼腹怎么吃:水煮,鱼背怎么吃:刺多,油炸(deep fry)。
先有一条被烹饪的鱼类
class CookedFish{
public:
String m_fishHead = "未处理鱼头";
String m_fishtail = "未处理鱼尾";
String m_fishBelly = "未处理鱼腹";
String m_fishBack = "未处理鱼背";
String m_fishType = "未知鱼类";
void HasBeenEat(){
std::cout << "烹饪" << m_fishType << "; 鱼头:" << m_fishHead << "; 鱼尾:" << m_fishtail << "; 鱼腹:" << m_fishBelly << "; 鱼背:" << std::endl;
}
}
现在需要一个烹饪builder,来具体决定怎样对鱼进行烹饪
class CookedFishBuilder{
CookedFish* fish;
CookedFishBuilder(){
fish - new CookedFish()
}
}
当然如果后续的创建的 builder 能够有相同属性的操作的话,也可以抽象成一个接口:
class Builder {
virtual ~Builder(){};
virtual void reCook(){} = 0;
virtual void CookFishHead() = 0;
virtual void CookFishTail() = 0;
virtual void CookFishBelly() = 0;
virtual void CookFishBack() = 0;
virtual CookedFish* GetCookedFish() = 0;
}
具体的生成器直接继承该接口
class CookedFishBuilder: public Builder{
private:
CookedFish* cookedFish;
~CookedFishBuilder(){
delete cookedFish;
}
CookedFishBuilder(){
Reset();
}
virtual void CookFishHead override(){
cookedFish->m_fishHead = "清蒸";
}
virtual void CookFishTail override(){
cookedFish->m_fishtail = "红烧";
}
virtual void CookFishBelly override(){
cookedFish->m_fishBelly = "水煮";
}
virtual void CookFishBack override(){
cookedFish->m_fishBack = "油炸";
}
virtual void Reset() override {
cookedFish = new CookedFish();
}
virtual CookedFish* GetCookedFish() override {
CookedFish* outputFish = cookedFish;
Reset();
return outputFish;
}
}
那么我现在需求变了:我想换换口味,整条鱼都油炸
现在只需要新建一个builder即可
class DeepFriedFishBuilder: public Builder{
private:
CookedFish* cookedFish;
~DeepFriedFishBuilder(){
delete cookedFish;
}
DeepFriedFishBuilder(){
Reset();
}
virtual void CookFishHead override(){
cookedFish->m_fishHead = "deep fry";
}
virtual void CookFishTail override(){
cookedFish->m_fishtail = "deep fry";
}
virtual void CookFishBelly override(){
cookedFish->m_fishBelly = "deep fry";
}
virtual void CookFishBack override(){
cookedFish->m_fishBack = "deep fry";
}
virtual void Reset() override {
cookedFish = new CookedFish();
}
virtual CookedFish* GetCookedFish() override {
CookedFish* outputFish = cookedFish;
Reset();
return outputFish;
}
}
主管
现在我有两个builder,如果烹饪的步骤非常固定,我们可以增加一个角色(Director)
class FishDirector {
public:
CookedFish MakeFish(CookedFishBuilder& builder)
{
builder.SetFishType("鲤鱼");
builder.CookFishHead();
builder.CookFishTail();
builder.CookFishBelly();
builder.CookFishBack();
return builder.GetCookedFish();
}
};
在主业务代码中使用主管
int main() {
CookedFishBuilder builder;
FishDirector director;
CookedFish fish = director.MakeFish(builder);
fish.HasBeenEat();
delete fish
return 0;
}
工厂模式解决的是:我该生产什么,获得什么鱼
构建者模式解决的是:这条鱼我该怎么烹饪,以什么方式烹饪,什么顺序烹饪
在这里Director不是必要的。其实预期使用delete,使用unique_ptr更好,避免忘记释放空间
浙公网安备 33010602011771号