C++抽象工厂模式(Abstract Factory Pattern)

意图

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

动机

考虑一个支持多种视感标准的用户界面工具包,例如Motif和Presentation Manager。不同的视感风格为诸如滚动条、窗口和按钮等用户界面“窗口组件”定义不同的外观和行为。为保证视感风格标准间的可移植性,一个应用不应该为特定的视感外观硬编码它的窗口组件。在整个应用中实例化特定视感风格的窗口组件类将使得以后很难改变视感风格。

适用性

  • 一个系统要独立于它的产品的创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 当你要强调一系列相关的产品对的设计以便进行联合使用时。
  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

类图

在这里插入图片描述

例子场景

假设你有一家披萨店,每个披萨需要做一些准备(和面、加上佐料),然后烘烤、切片、装盒,每个调料都是这家店特有的工厂提供。

实现

PizzaStore.h

#pragma once

#include <string>

class Pizza;
class PizzaStore
{
public:
	PizzaStore();
	void orderPizza(const std::string& pizzaName);
	virtual Pizza* createPizza(const std::string& pizzaName)=0;
};

PizzaStore.cpp

#include "PizzaStore.h"
#include "Pizza.h"
#include <memory>

PizzaStore::PizzaStore()
{
}

void PizzaStore::orderPizza(const std::string& pizzaName)
{
	std::shared_ptr<Pizza> pPizza;
	pPizza.reset(createPizza(pizzaName));

	pPizza->prepare();
	pPizza->bake();
	pPizza->cut();
	pPizza->box();
}

PizzaStore.h

#pragma once

#include "PizzaStore.h"

class Pizza;
class NYPizzaStore : public PizzaStore
{
public:
	NYPizzaStore();
	Pizza *createPizza(const std::string& pizzaName) override;
};

PizzaStore.cpp

#include "NYPizzaStore.h"
#include "NYStyleCheesePizza.h"
#include "NYPizzaIngredientFactory.h"

NYPizzaStore::NYPizzaStore()
{

}

Pizza* NYPizzaStore::createPizza(const std::string& pizzaName)
{
	Pizza* pPizza = nullptr;
	if (pizzaName == "Cheese")
	{
		pPizza = new NYStyleCheesePizza(new NYPizzaIngredientFactory());
	}
	
	return pPizza;
}

Pizza.h

#pragma once

#include <string>
#include <vector>

class Dough;
class Sauce;
class Cheese;
class PizzaIngredientFactory;
class Pizza
{
public:
	Pizza();
	virtual void prepare()=0;
	virtual void bake();
	virtual void cut();
	virtual void box();
protected:
	std::string m_name;
	Dough* m_pDough;
	Sauce* m_pSauce;
	Cheese* m_pCheese;
	PizzaIngredientFactory* m_pPizzaIngredientFactory;
};

Pizza.cpp

#include "Pizza.h"
#include <iostream>

Pizza::Pizza()
{
}

void Pizza::bake()
{
	std::cout << "Bake for 25 minutes at 350"<<std::endl;
}

void Pizza::cut()
{
	std::cout << "Cutting the pizza into diagonal slices" << std::endl;
}

void Pizza::box()
{
	std::cout << "Place pizza in official PizzaStore box" << std::endl;
}

NYStyleCheesePizza.h

#pragma once
#include "Pizza.h"

class PizzaIngredientFactory;
class NYStyleCheesePizza : public Pizza
{
public:
	NYStyleCheesePizza(PizzaIngredientFactory* pPizzaIngredientFactory);
	void prepare() override;
};

NYStyleCheesePizza.cpp

#include "NYStyleCheesePizza.h"
#include "PizzaIngredientFactory.h"
#include "Dough.h"
#include "Cheese.h"
#include "Sauce.h"
#include <iostream>

NYStyleCheesePizza::NYStyleCheesePizza(PizzaIngredientFactory* pPizzaIngredientFactory)
{
	m_name = "NY Style Sauce and Cheese Pizza";
	m_pPizzaIngredientFactory = pPizzaIngredientFactory;
}

void NYStyleCheesePizza::prepare()
{
	std::cout << "Prepareing " << m_name << std::endl;
	m_pDough = m_pPizzaIngredientFactory->createDough();
	m_pCheese = m_pPizzaIngredientFactory->createCheese();
	m_pSauce = m_pPizzaIngredientFactory->createSauce();

	std::cout << "Dough:" << m_pDough->getDescription() << std::endl;
	std::cout << "Sauce:" << m_pSauce->getDescription() << std::endl;
	std::cout << "Cheese:" << m_pCheese->getDescription() << std::endl;
}

Cheese.h

#pragma once

#include <iostream>

class Cheese
{
public:
	Cheese();
	virtual std::string getDescription() = 0;
};

Cheese.cpp

#include "Cheese.h"

Cheese::Cheese()
{
}

ReggianoCheese.h

#pragma once
#include "Cheese.h"
class ReggianoCheese : public Cheese
{
public:
	ReggianoCheese();
	std::string getDescription() override;
};

ReggianoCheese.cpp

#include "ReggianoCheese.h"
#include <iostream>

ReggianoCheese::ReggianoCheese()
{
}

std::string ReggianoCheese::getDescription()
{
	return "Reggiano Cheese";
}

Dough.h

#pragma once

#include <iostream>

class Dough
{
public:
	Dough();
	virtual std::string getDescription() = 0;
};

Dough.cpp

#include "Dough.h"

Dough::Dough()
{
}

ThinCrustDough.h

#pragma once

#include "Dough.h"
#include <string>

class ThinCrustDough : public Dough
{
public:
	ThinCrustDough();
	std::string getDescription() override;
};

ThinCrustDough.cpp

#include "ThinCrustDough.h"
#include <iostream>

ThinCrustDough::ThinCrustDough()
{
}

std::string ThinCrustDough::getDescription()
{
	return "Thin Crust Dough";
}

Sauce.h

#pragma once

#include <iostream>

class Sauce
{
public:
	Sauce();
	virtual std::string getDescription() = 0;
};

Sauce.cpp

#include "Sauce.h"

Sauce::Sauce()
{
}

MarinaraSauce.h

#pragma once
#include "Sauce.h"

class MarinaraSauce : public Sauce
{
public:
	MarinaraSauce();
	std::string getDescription() override;
};

MarinaraSauce.cpp

#include "MarinaraSauce.h"
#include <iostream>

MarinaraSauce::MarinaraSauce()
{
}

std::string MarinaraSauce::getDescription()
{
	return "Marinara Sauce";
}

main.cpp

#include "NYPizzaStore.h"
#include <memory>
#include <iostream>

int main()
{
	std::shared_ptr<PizzaStore> pNYPizzaStore = std::make_shared<NYPizzaStore>();
	pNYPizzaStore->orderPizza("Cheese");

	return 0;
}

输出

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值