工厂模式
工厂模式提供了一种创建对象的方式。它将创建的过程隐藏了起来,调用者只负责获取,不关心创建的细节。
具体使用场景来说,就是一个接口类,在不同的场景,需要不同的子类,这个时候就可以使用工厂类,根据提供的参数来返回不同子类的实例。
举个例子:
用户说我想要一个笔记本电脑。
工厂类说,我们这里有三种电脑:逼格高的,光污染的,超轻薄的。
用户想了想说,那就逼格高的吧。
然后工厂类从柜台掏出一台MacBook递给用户。
其实这里用户并不关心你返回的具体是哪个子类,他只关心,你给我的子类符合我传给你的参数。
工厂类便是实现这样的功能,将需求转化为具体的实例。当然,多数情况下,需求本身可能就是子类的名称,比如用户说,我就想要一台苹果电脑。
// LapTop.h
#pragma once
// 抽象类
class LapTop
{
public:
LapTop() = default;
virtual void powerOn() = 0;
virtual void shutDown() = 0;
}
//LapTopImpl.h
#pragma once
#include "LapTop.h"
#include <iostream>
class MacBook final : public LapTop
{
public:
MacBook() : LapTop() {};
virtual void powerOn() override
{
std::cout << "Hello! Welcome to use MacBook!" << std::endl;
}
virtual void shutDown() override
{
std::cout << "Goodbye! Thanks to use MacBook!" << std::endl;
}
}
class Allienware final : public LapTop
{
public:
Allienware() : LapTop() {};
virtual void powerOn() override
{
std::cout << "Hello! Welcome to use Allienware!" << std::endl;
}
virtual void shutDown() override
{
std::cout << "Goodbye! Thanks to use Allienware!" << std::endl;
}
}
class ThinkPad final : public LapTop
{
public:
ThinkPad() : LapTop() {};
virtual void powerOn() override
{
std::cout << "Hello! Welcome to use ThinkPad!" << std::endl;
}
virtual void shutDown() override
{
std::cout << "Goodbye! Thanks to use ThinkPad!" << std::endl;
}
}
}
// LapTopFactory.h
#pragma once
#include "LapTop.h"
enum class LapTopBrand
{
MACBOOK,
ALLIENWARE,
THINKPAD
}
//工厂类
class LapTopFactory
{
public:
LapTop* getLapTop(LapTopBrand brand);
}
// LapTopFactory.cpp
#include "LapTopFactory.h"
#include "LapTopImpl.h"
LapTop* LapTopFactory::getLapTop(LapTopBrand brand)
{
switch(brand)
{
case LapTopBrand::MACBOOK:
{
return new MacBook;
}
case LapTopBrand::ALLIENWARE:
{
return new Allienware;
}
case LapTopBrand::THINKPAD:
{
return new ThinkPad;
}
default:
{
return nullptr;
}
}
//main.cpp
#include "LapTopFactory.h"
int main(void)
{
LapTopFactory f;
LapTop* ptr = f.getLapTop(LapTopBrand::MACBOOK);
ptr->powerOn();
ptr->shutDown();
delete ptr;
ptr = f.getLapTop(LapTopBrand::ALLIENWARE);
ptr->powerOn();
ptr->shutDown();
delete ptr;
ptr = f.getLapTop(LapTopBrand::THINKPAD);
ptr->powerOn();
ptr->shutDown();
delete ptr;
return 0;
}
可以看到,当外界调用时,它只看到了两个类:LapTop和LapTopFactory。对于LapTopFactory如何构造LapTop,使用的new还是资源池(一手还是二手的LapTop)并不关心。此时就可以使用工厂模式。
该类和建造者类有一定的相似,具体我会在建造者类里说明。