一,工厂方法模式的定义
工厂方法模式是一种创建型设计模式,它提供了一种创建对象的方法,而无需指定具体的类,也不需要直接指定对象的类型。
工厂方法模式抽象了对象的创建过程,使得客户端只需要通过指定具体的参数,而无需关心对象的创建细节。
工厂方法模式将创建对象的逻辑封装在一个类(工厂类)中,它提供了一种通过调用工厂类的方法来创建对象的方式,而无需直接使用对象的构造函数,外部客户端通过调用工厂类的方法来获取所需的对象。
由于工厂方法模式将创建对象的逻辑封装在了一个工厂类中,这种设计可以让对象的创建与使用的解耦,提高了代码的灵活性和可维护性。
工厂方法模式在现实生活中的抽象实例:
餐厅点餐:餐厅根据顾客的下单来订做相应的食物。
汽车制造:汽车厂商通过固定的工厂流水线生产不同型号和外观的汽车。
服装定制:顾客在服装店通过选择设计、尺寸和面料等要素来定制自己的服装。
二,工厂方法模式的结构
工厂方法模式主要包含以下组件:
1.抽象工厂(Factory):
定义创建产品的接口,包含创建产品对象的抽象方法。
2.具体工厂(Concrete Factory):
是抽象工厂的具体实现,负责创建具体的产品对象,具体工厂根据调用场景来决定实例化哪一个具体产品类,并返回该产品的实例。
3.抽象产品(Product):
定义了产品的主要特性和功能。
4.具体产品(Concrete Product):
是抽象产品的具体实现。
组件之间的工作步骤如下:
1.客户端通过调用具体工厂的方法来创建产品。客户端并不知道具体的产品类,只知道抽象接口。
2.具体工厂接收到客户端的请求后,根据一定的条件来决定实例化哪一类具体产品,并调用具体产品类的构造函数。
3.具体产品类实例化后,将产品返回给客户端使用。
对应UML类图:
三,工厂方法模式代码样例
include
class Product {
public:
virtual void use() = 0;
};
class ConcreteProductA: public Product{
public:
void use() {
std::cout << “Using ConcreteProductA” << std::endl;
}
};
class ConcreteProductB: public Product{
public:
void use() {
std::cout << “Using ConcreteProductB” << std::endl;
}
};
class Factory{
public:
virtual Product* createProduct() = 0;
};
class ConcreteFactoryA: public Factory{
public:
Product* createProduct() {
return new ConcreteProductA();
}
};
class ConcreteFactoryB: public Factory{
public:
Product* createProduct() {
return new ConcreteProductB();
}
};
int main() {
Factory* factoryA = new ConcreteFactoryA();
Product* productA = factoryA->createProduct();
productA->use();
Factory* factoryB = new ConcreteFactoryB();
Product* productB = factoryB->createProduct();
productB->use();
delete factoryA;
delete productA;
delete factoryB;
delete productB;
return 0;
}
运行结果:
Using ConcreteProductA
Using ConcreteProductB
四,工厂方法模式的优缺点
工厂方法模式的优点:
将对象的创建与使用分离,客户端无需知道具体的产品类,也不需要知道具体产品的实现细节。
降低了客户端和具体产品类之间的耦合度。
如果需要更换具体产品类,只需要修改工厂类的实现即可,而不需要修改客户端的代码。
可以在工厂类中实现对象的生命周期管理和对象池等功能。
可以在工厂类中实现对象的复用,如果多个客户端需要同一个对象,可以通过工厂类实现对象的共享,避免重复创建对象。
工厂方法模式的缺点:
引入工厂类之后,系统会多出一个类,增加了代码的复杂度和理解难度。
需要额外的工厂类来创建对象,会带来一定的性能开销。
只适用于创建具有相同接口或基类的对象,如果需要创建具有不同接口的对象,该模式不适用。
五,代码实战
Demo1:
include
class Product {
public:
virtual ~Product() {}
virtual void operation() = 0;
};
class Factory {
public:
virtual ~Factory() {}
virtual Product* createProduct() = 0;
};
class ProductA : public Product {
public:
void operation() override {
std::cout << “Performing Operation A…” << std::endl;
}
};
class ProductB : public Product {
public:
void operation() override {
std::cout << “Performing Operation B…” << std::endl;
}
};
class FactoryA : public Factory {
public:
Product* createProduct() override { return new ProductA(); }
};
class FactoryB : public Factory {
public:
Product* createProduct() override { return new ProductB(); }
};
int main() {
Factory* factoryA = new FactoryA();
Product* productA = factoryA->createProduct();
productA->operation();
Factory* factoryB = new FactoryB();
Product* productB = factoryB->createProduct();
productB->operation();
return 0;
}
运行结果:
Performing Operation A…
Performing Operation B…
Demo2:
include
include
include
using namespace std;
//Abstract Product
class Page
{
public:
virtual string GetPageName(void) = 0;
};
//Concrete Product
class SkillsPage : public Page
{
public:
string GetPageName(void)
{
return “SkillsPage”;
}
};
//Concrete Product
class EducationPage : public Page
{
public:
string GetPageName(void)
{
return “EducationPage”;
}
};
//Concrete Product
class ExperiencePage : public Page
{
public:
string GetPageName(void)
{
return “ExperiencePage”;
}
};
//Concrete Product
class IntroductionPage : public Page
{
public:
string GetPageName(void)
{
return “IntroductionPage”;
}
};
//Concrete Product
class ResultsPage : public Page
{
public:
string GetPageName(void)
{
return “ResultsPage”;
}
};
//Concrete Product
class ConclusionPage : public Page
{
public:
string GetPageName(void)
{
return “ConclusionPage”;
}
};
//Concrete Product
class SummaryPage : public Page
{
public:
string GetPageName(void)
{
return “SummaryPage”;
}
};
//Concrete Product
class BibliographyPage : public Page
{
public:
string GetPageName(void)
{
return “BibliographyPage”;
}
};
//Abstract Factory
class Document
{
public:
Document()
{
}
void AddPages(Page* page)
{
pages_.push_back(page);
}
const list>& GetPages(void) { return pages_; } //Factory Method virtual void CreatePages(void) = 0; private: list> pages_;
};
//Concrete Factory
class Resume : public Document
{
public:
Resume()
{
CreatePages();
}
void CreatePages(void)
{
AddPages(new SkillsPage());
AddPages(new EducationPage());
AddPages(new ExperiencePage());
}
};
//Concrete Factory
class Report : public Document
{
public:
Report()
{
CreatePages();
}
void CreatePages(void)
{
AddPages(new SummaryPage());
AddPages(new IntroductionPage());
AddPages(new ResultsPage());
AddPages(new ConclusionPage());
AddPages(new BibliographyPage());
}
};
int main()
{
Document* doc1 = new Resume();
Document* doc2 = new Report();
//Get and print the pages of the first document
list>& doc1Pages = const_cast>&> (doc1->GetPages());
cout << “\nResume Pages ————-” << endl; for (list>::iterator it = doc1Pages.begin(); it != doc1Pages.end(); it++) { cout << “\t” << (it)->GetPageName() << endl; } //Get and print the pages of the second document list>& doc2Pages = const_cast>&> (doc2->GetPages());
cout << “\nReport Pages ————-” << endl; for (list>::iterator it = doc2Pages.begin(); it != doc2Pages.end(); it++) { cout << “\t” << (it)->GetPageName() << endl;
}
return 0;
}
运行结果:
Resume Pages ————-
SkillsPage
EducationPage
ExperiencePage
Report Pages ————-
SummaryPage
IntroductionPage
ResultsPage
ConclusionPage
BibliographyPage
六,参考阅读
https://www.codeproject.com/Articles/570183/Factory-Method-Pattern
https://artofcoding.dev/design-patterns-factory-and-factory-method
https://sourcemaking.com/design_patterns/factory_method
https://www.geeksforgeeks.org/factory-method-for-designing-pattern/
https://advancedcppwithexamples.blogspot.com/2010/08/c-example-for-factory-method-design.html
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/423152.html