【设计模式】创建型模式之抽象工厂Abstract Factory

时间:2022-09-08 20:05:11

抽象工厂Abstract Factory是一种创建型设计模式,目的在于提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂的类图如下,客户仅与抽象类定义的定义的接口交互,而不使用特定的具体类的接口。一个系统包含多种产品时,AbstractFactory声明创建各种抽象产品对象的操作接口,这些接口是直接暴露给Client的,而具体产品对象的创建则延迟到子类ConcreteFactory,Client面对的产品类是AbstractProduct,无需关系具体产品类是什么。在运行时刻,为创建不同的产品对象,客户应使用不同的具体工厂,创建ConcreteFactory类的实例,具体工厂负责创建特定的产品对象。

【设计模式】创建型模式之抽象工厂Abstract Factory

以一个例子说明抽象工厂的用法,与上面类图的对应关系如下:

AbstractFactory——PhoneFactory
AbstractFactory::createProductA——PhoneFactory::createGlass
AbstractFactory::createProductB——PhoneFactory::createCamera
ConcreteFactory1——IPhoneFactory
ConcreteFactory1::createProductA——IPhoneFactory::createGlass
ConcreteFactory1::createProductB——IPhoneFactory::createCamera
ConcreteFactory2——NexusFactory
ConcreteFactory2::createProductA——NexusFactory::createGlass
ConcreteFactory2::createProductB——NexusFactory::createCamera
AbstractProductA——Glass
ProductA1——IPhoneGlass
ProductA2——NexusGlass
AbstractProductB——Camera
ProductB1——IPhoneCamera
ProductB2——NexusCamera
Client——MakePhone

另外,例子中还有一款产品Phone,并没有像GlassCamera那样作为基类来使用,而是一个一般的类,这是抽象产品的具类表现,对应的抽象工厂与具体工厂也有createPhone接口。

代码如下:

/*
* @class Glass
*/

class Glass
{
public:
Glass();
virtual std::string glassType() const;
};

/*
* @class IPhoneGlass
*/

class IPhoneGlass : public Glass
{
public:
IPhoneGlass();
std::string glassType() const;
};

/*
* @class NexusGlass
*/

class NexusGlass : public Glass
{
public:
NexusGlass();
std::string glassType() const;
};

/*
* @class Camera
*/

class Camera
{
public:
Camera();
virtual std::string cameraType() const;
};

/*
* @class IPhoneCamera
*/

class IPhoneCamera : public Camera
{
public:
IPhoneCamera();
std::string cameraType() const;
};

/*
* @class NexusCamera
*/

class NexusCamera : public Camera
{
public:
NexusCamera();
std::string cameraType() const;
};

/*
* @class Phone
*/

class Phone
{
public:
Phone();
void addGlass(Glass *glass);
Glass* getGlass();
void addCamera(Camera *camera);
Camera* getCamera();

private:
Glass *m_glass;
Camera *m_camera;
};

/*
* @class PhoneFactory
*/

class PhoneFactory
{
public:
PhoneFactory();
virtual Phone* createPhone();
virtual Glass* createGlass();
virtual Camera* createCamera();
};

/*
* @class IPhoneFactory
*/

class IPhoneFactory : public PhoneFactory
{
public:
IPhoneFactory();
Phone* createPhone();
Glass* createGlass();
Camera* createCamera();
};

/*
* @class NexusFactory
*/

class NexusFactory : public PhoneFactory
{
public:
NexusFactory();
Phone* createPhone();
Glass* createGlass();
Camera* createCamera();
};

/*
* @class Client
*/

class Client
{
public:
Client();
Phone* makePhone(PhoneFactory *phone);
};
/* Glass */
Glass::Glass()
{
}

std::string Glass::glassType() const
{
return std::string("Unknown Glass");
}

/* IPhoneGlass */
IPhoneGlass::IPhoneGlass()
{
}

std::string IPhoneGlass::glassType() const
{
return std::string("IPhone Glass");
}

/* NexusGlass */
NexusGlass::NexusGlass()
{
}

std::string NexusGlass::glassType() const
{
return std::string("Nexus Glass");
}

/* Camera */
Camera::Camera()
{
}

std::string Camera::cameraType() const
{
return std::string("Unknown Camera");
}

/* IPhoneCamera */
IPhoneCamera::IPhoneCamera()
{
}

std::string IPhoneCamera::cameraType() const
{
return std::string("IPhone Camera");
}

/* NexusCamera */
NexusCamera::NexusCamera()
{
}

std::string NexusCamera::cameraType() const
{
return std::string("Nexus Camera");
}

/* Phone */
Phone::Phone()
: m_glass(0)
, m_camera(0)
{
}

void Phone::addGlass(Glass *glass)
{
m_glass = glass;
}

Glass* Phone::getGlass()
{
return m_glass;
}

void Phone::addCamera(Camera *camera)
{
m_camera = camera;
}

Camera* Phone::getCamera()
{
return m_camera;
}

/* PhoneFactory */
PhoneFactory::PhoneFactory()
{
}

Phone* PhoneFactory::createPhone()
{
return 0;
}

Glass* PhoneFactory::createGlass()
{
return 0;
}

Camera* PhoneFactory::createCamera()
{
return 0;
}

/* IPhoneFactory */
IPhoneFactory::IPhoneFactory()
{
}

Phone* IPhoneFactory::createPhone()
{
return new Phone;
}

Glass* IPhoneFactory::createGlass()
{
return new IPhoneGlass;
}

Camera* IPhoneFactory::createCamera()
{
return new IPhoneCamera;
}

/* NexusFactory */
NexusFactory::NexusFactory()
{
}

Phone* NexusFactory::createPhone()
{
return new Phone;
}

Glass* NexusFactory::createGlass()
{
return new NexusGlass;
}

Camera* NexusFactory::createCamera()
{
return new NexusCamera;
}

/* Client */
Client::Client()
{
}

Phone* Client::makePhone(PhoneFactory *phone)
{
if (phone) {
Phone *myPhone = phone->createPhone();
Glass *glass = phone->createGlass();
Camera *camera = phone->createCamera();
myPhone->addGlass(glass);
myPhone->addCamera(camera);
std::cout << myPhone->getGlass()->glassType() << std::endl;
std::cout << myPhone->getCamera()->cameraType() << std::endl;

return myPhone;
}
return 0;
}

测试代码如下:

    IPhoneFactory iphone;
Client client;
client.makePhone(&iphone);

NexusFactory nexus;
Client client2;
client2.makePhone(&nexus);

例子中,Client使用一个AbstractFactory作为参数来创建手机,为了创建不同类型的手机,需要使用AbstractFactory的子类的对象作为参数,即IPhoneFactory或者NexusFactory,手机类型为IPhone或者Nexus,首先创建手机Phone,然后创建各自的零部件Glass和Camera,它们的类型与其手机的类型相符,glassType和cameraType函数可以验证我们的零部件类型是否正确。可以看出,makePhone在创建手机时,使用的是抽象工厂、抽象产品类,并不知道具体的实现类的细节,这便是抽象工厂设计模式的目的,分离了具体的实现类,使用了虚函数及类型自动向上转化的特点,即子类类型自动转为父类类型。