设计模式中的工厂模式,在项目中使用还是很频繁,工厂模式细分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。
## 简单工厂模式
class Widget
{
public:
typedef enum
{
WidgetA = 0,
WidgetB
}Type;
explicit Widget(Type type) :m_type(type)
{
}
virtual ~Widget()
{
}
protected:
Type m_type;
};
class WidgteA : public Widget
{
public:
explicit WidgteA(Type type) :Widget(type)
{
std::cout << "创建A窗口" << std::endl;
}
};
class WidgteB : public Widget
{
public:
explicit WidgteB(Type type) :Widget(type)
{
std::cout << "创建B窗口" << std::endl;
}
};
class FactoryWidget
{
public:
explicit FactoryWidget(){}
Widget* WinFactory(Widget::Type type)
{
switch (type)
{
case Widget::WidgetA:
return new WidgteA(type);
case Widget::WidgetB:
return new WidgteB(type);
default:
break;
}
return nullptr;
}
};
简单工厂模式的优缺点:
优点:简单,容易理解,但是违背设计原则中的开闭原则
缺点:就上面的例子,如果增加一个新的窗口,就要修改原先的代码很不方便
## 工厂方法模式
class Actor
{
public:
explicit Actor(int type, std::string name)
: m_iType(type)
, m_strName(name)
{
}
virtual ~Actor()
{
}
private:
int m_iType;
std::string m_strName;
};
class ActorA : public Actor
{
public:
explicit ActorA(int type, std::string name)
: Actor(type, name)
{
std::cout << "角色创建:"<< name << std::endl;
}
virtual ~ActorA()
{
}
};
class ActorB : public Actor
{
public:
explicit ActorB(int type, std::string name)
: Actor(type, name)
{
std::cout << "角色创建:"<<name << std::endl;
}
virtual ~ActorB()
{
}
};
//
class Factory
{
public:
explicit Factory(int type, const std::string name)
: m_iType(type)
, m_strName(name)
{
}
virtual ~Factory()
{
}
virtual Actor* creatFactory()
{
return new Actor(m_iType, m_strName);
}
protected:
int m_iType;
std::string m_strName;
};
class FactoryA : public Factory
{
public:
explicit FactoryA(int type, const std::string name)
: Factory(type, name)
{
std::cout << "工厂:" << name << std::endl;
}
Actor* creatActor()
{
return new ActorA(m_iType, m_strName);
}
};
class FactoryB : public Factory
{
public:
explicit FactoryB(int type, const std::string name)
: Factory(type, name)
{
std::cout << "工厂:" << name << std::endl;
}
Actor* creatActor()
{
return new ActorB(m_iType, m_strName);
}
};
template<typename T>
class ActorFactory
{
public:
explicit ActorFactory()
{
}
virtual ~ActorFactory()
{
}
T* creatorFactory(const int type, const std::string name)
{
return new T(type, name);
}
};
工厂方法模式的优缺点:
优点:上面的例子如果增加新的角色,直接派生基类增加,和增加新的工厂即可,不影响原来的代码,符合开闭原则
缺点:一个工厂只能进行一个角色的诞生,有多少角色就有多少工厂,
## 抽象工厂模式
class Body
{
public:
explicit Body(std::string name) :m_strName(name)
{
}
virtual ~Body() {}
virtual std::string getBodyName() = 0;
protected:
std::string m_strName;
};
class Clothes
{
public:
explicit Clothes(std::string name) :m_strName(name)
{
}
virtual ~Clothes() {}
virtual std::string getClothesName() = 0;
protected:
std::string m_strName;
};
class Shoe
{
public:
explicit Shoe(std::string name)
: m_strName(name)
{
}
virtual ~Shoe() {}
virtual std::string getShoeName() = 0;
protected:
std::string m_strName;
};
class DollBody : public Body
{
public:
explicit DollBody(std::string name)
: Body(name)
{
}
std::string getBodyName()
{
return m_strName;
}
private:
};
class DollClothes : public Clothes
{
public:
explicit DollClothes(std::string name) :Clothes(name)
{
}
std::string getClothesName()
{
return m_strName;
}
private:
};
class DollShoe : public Shoe
{
public:
explicit DollShoe(std::string name) : Shoe(name)
{
}
std::string getShoeName()
{
return m_strName;
}
private:
};
class Doll
{
public:
explicit Doll( Body* pBody, Clothes* pClothes, Shoe* pShoe)
: m_pBody(pBody)
, m_pClothes(pClothes)
, m_pShoe(pShoe)
{
}
void Assemble()
{
std::cout << m_pBody->getBodyName() << std::endl;;
std::cout << m_pClothes->getClothesName() << std::endl;
std::cout << m_pShoe->getShoeName()<<std::endl;
}
private:
Body* m_pBody;
Clothes* m_pClothes;
Shoe* m_pShoe;
};
class FactoryAbs
{
public:
virtual ~FactoryAbs() {}
virtual Body* creatBody() = 0;
virtual Clothes* creatClothes() = 0;
virtual Shoe* creatShoe() = 0;
virtual std::string name() = 0;
protected:
std::string m_strName;
};
class ZheJiangFactory : public FactoryAbs
{
public:
explicit ZheJiangFactory(std::string name)
: m_strName(name)
{
}
virtual ~ZheJiangFactory()
{
}
Body* creatBody()
{
return new DollBody("浙江生产玩具身体");
}
Clothes* creatClothes()
{
return new DollClothes("浙江生产玩具衣服");
}
Shoe* creatShoe()
{
return new DollShoe("浙江生产玩具鞋");
}
std::string name()
{
return m_strName;
}
private:
std::string m_strName;
};
class JiangSuFactory : public FactoryAbs
{
public:
explicit JiangSuFactory(std::string name)
: m_strName(name)
{
}
virtual ~JiangSuFactory()
{
}
Body* creatBody()
{
return new DollBody("江苏生产玩具身体");
}
Clothes* creatClothes()
{
return new DollClothes("江苏生产玩具衣服");
}
Shoe* creatShoe()
{
return new DollShoe("江苏生产玩具鞋");
}
std::string name()
{
return m_strName;
}
private:
std::string m_strName;
};
抽象工厂模式的优缺点:
优点:代码扩展灵活,符合开闭原则
缺点:代码量大,复杂
方法调用
int main()
{
//工厂方法模式
Actor* pB = (new ActorFactory<FactoryB>())->creatorFactory(0, "B")->creatActor();
Actor* pA = (new ActorFactory<FactoryA>())->creatorFactory(0, "A")->creatActor();
//简单工厂模式
FactoryWidget* pFwin = new FactoryWidget();
Widget* pWinA = pFwin->WinFactory(Widget::WidgetA);
Widget* pWinB = pFwin->WinFactory(Widget::WidgetB);
//抽象工厂模式
FactoryAbs* pZheJiangFactory = new ZheJiangFactory("浙江工厂");
Body* pBody = pZheJiangFactory->creatBody();
Clothes* pClothes = pZheJiangFactory->creatClothes();
Shoe* pShoe = pZheJiangFactory->creatShoe();
Doll* pDoll = new Doll(pBody, pClothes, pShoe);
pDoll->Assemble();
FactoryAbs* pJiangSuFactory = new JiangSuFactory("江苏工厂");
Body* pBody1 = pJiangSuFactory->creatBody();
Clothes* pClothes1 = pJiangSuFactory->creatClothes();
Shoe* pShoe1 = pJiangSuFactory->creatShoe();
Doll* pDoll1 = new Doll(pBody1, pClothes1, pShoe1);
pDoll1->Assemble();
//多个工厂配合生产一个产品
FactoryAbs* pZheJiangFactory1 = new ZheJiangFactory("浙江工厂");
Body* pZJBody = pZheJiangFactory1->creatBody();
FactoryAbs* pJiangSuFactory1 = new JiangSuFactory("江苏工厂");
Clothes* pJSClothes1 = pJiangSuFactory1->creatClothes();
Shoe* pJSShoe1 = pJiangSuFactory1->creatShoe();
Doll* pM = new Doll(pZJBody, pJSClothes1, pJSShoe1);
pM->Assemble();
return 0;
}
以上就是工厂模式中的三种模式,各有优缺点,如果不牵扯到代码的扩展,用简单的工厂模式,简单方便,容易理解,如果有代码的扩展需求,工厂方法模式比较合适,但是,需要定义很多工厂,工厂代码太多,如果牵扯一个工厂有多个产品线,那只能使用抽象工厂模式,代码量大,比较复杂,所以在项目开发过程中,选择适合自己的设计模式是最重要的,灵活变通。