概念:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。
主要作用:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
解决的问题:工厂一旦需要生产新产品就需要修改工厂类的方法逻辑,违背了“开放 - 关闭原则
实现原理:本质上是通过虚函数、纯虚函数、继承的多态性实现的。
模式组成
组成(角色) 关系 作用
抽象产品(Product) 具体产品的父类 描述具体产品的公共接口
具体产品(Concrete Product) 抽象产品的子类;工厂类创建的目标类 描述生产的具体产品
抽象工厂(Creator) 具体工厂的父类 描述具体工厂的公共接口
具体工厂(Concrete Creator) 抽象工厂的子类;被外界调用 描述具体工厂;实现
使用步骤
步骤1: 创建抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
步骤3: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
重点在于:具体工厂类创建对应的具体产品类。工厂关联产品
优点:
更符合开-闭原则
新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
符合单一职责原则
每个具体工厂类只负责创建对应的产品
让扩展变得简单,让继承变得可行,增加了多态性的体现。
缺点:
1.系统类数增多,增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
2.引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
3.一个具体工厂只能创建一种具体产品
适用场景:
(1) 客户端不知道它所需要的对象的类。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
(2) 抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
c++ 代码例子:
#pragma once
#include <memory>
//产品
class CMouse
{
public:
CMouse();
~CMouse();
virtual void sayHi() ;
};
class CDellMouse :public CMouse
{
public:
CDellMouse ();
virtual ~ CDellMouse ();
void sayHi() override;
};
class CHpMouse :public CMouse
{
public:
CHpMouse();
virtual ~CHpMouse();
void sayHi() override;
};
using Mouseptr = std::shared_ptr<CMouse>;
工厂模式
class CFactoryMethod
{
public:
CFactoryMethod();
virtual ~CFactoryMethod();
virtual CMouse * CreateMouse() = 0;
virtual Mouseptr CreateMousePtr() = 0;
};
class CHpmouseFactory :public CFactoryMethod
{
public:
CHpmouseFactory();
virtual ~CHpmouseFactory();
CMouse *CreateMouse() override;
Mouseptr CreateMousePtr() override;
private:
};
class CDellmouseFactory :public CFactoryMethod
{
public:
CDellmouseFactory();
virtual ~CDellmouseFactory();
CMouse *CreateMouse() override;
Mouseptr CreateMousePtr() override;
private:
};
#include "pch.h"
#include "SimpleFactory.h"
#include <iostream>
CMouse::CMouse()
{
}
CMouse::~CMouse()
{
}
void CMouse::sayHi()
{
printf(" mouse");
}
CDellMouse::CDellMouse()
{
}
void CDellMouse::sayHi()
{
printf("Dell mouse") ;
}
CDellMouse ::~CDellMouse()
{
}
CHpMouse::CHpMouse()
{
}
CHpMouse::~CHpMouse()
{
}
void CHpMouse::sayHi()
{
printf("hp mouse");
}
CFactoryMethod::CFactoryMethod()
{
}
CFactoryMethod::~CFactoryMethod()
{
}
CHpmouseFactory::CHpmouseFactory()
{
}
CHpmouseFactory::~CHpmouseFactory()
{
}
CMouse *CHpmouseFactory::CreateMouse()
{
CMouse *pMouse = new CHpMouse();
return pMouse;
}
Mouseptr CHpmouseFactory::CreateMousePtr()
{
Mouseptr Mouse = std::make_shared<CHpMouse>();
return Mouse;
}
CDellmouseFactory::CDellmouseFactory()
{
}
CDellmouseFactory::~CDellmouseFactory()
{
}
CMouse * CDellmouseFactory::CreateMouse()
{
CMouse *pMouse = new CDellMouse();
return pMouse;
}
Mouseptr CDellmouseFactory::CreateMousePtr()
{
Mouseptr Mouse = std::make_shared<CDellMouse>();
return Mouse;
}
void TestFactoryMethodPattern()
{
CFactoryMethod *pFactoryMethod = new CHpmouseFactory();
if (pFactoryMethod)
{
CMouse *pMouse = pFactoryMethod->CreateMouse();
if (pMouse)
{
pMouse->sayHi();
delete pMouse;
}
Mouseptr Mouse = pFactoryMethod->CreateMousePtr();
if (Mouse)
{
Mouse->sayHi();
}
delete pFactoryMethod;
}
}