Factory
简单工厂模式
Simple工厂模式描述了一个类,该类有一个创建方法,该方法有一个很大的条件,该条件根据方法参数选择要实例化的产品类,然后返回。人们通常会将简单工厂与一般工厂或一种创造性设计模式混淆。在大多数情况下,简单工厂是引入工厂方法或抽象工厂模式的中间步骤。
一个简单的工厂通常由一个类中的一个方法表示。随着时间的推移,这个方法可能会变得太大,因此您可能决定将该方法的部分提取到子类中。一旦您多次这样做,您可能会发现整个事情变成了经典的工厂方法模式。顺便说一下,如果你声明一个简单的工厂抽象,它不会神奇地变成抽象工厂模式。
class UserFactory {
public static function create($type) {
switch ($type) {
case 'user': return new User();
case 'customer': return new Customer();
case 'admin': return new Admin();
default:
throw new Exception('Wrong user type passed.');
}
}
}
工厂类:创建指定具体实例对象的接口
抽象产品类:具体产品类的父类或接口
具体产品类:工厂类创建的对象是具体产品类的实例
特点:工厂类封装了创建产品对象的函数
缺点:扩展差,新增产品的时候需要修改工厂类
例:
// 鞋子抽象类
class Shoes //interface
{
public:
virtual ~Shoes() {}
virtual void Show() = 0;
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
}
};
// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;
}
};
// 李宁鞋子
class LiNingShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;
}
};
//ShoesFactory为工厂类,类里实现根据鞋子类型创建对应鞋子产品对象的CreateShoes(SHOES_TYPE type)函数。
enum SHOES_TYPE
{
NIKE,
LINING,
ADIDAS
};
// 总鞋厂
class ShoesFactory
{
public:
// 根据鞋子类型创建对应的鞋子对象
Shoes *CreateShoes(SHOES_TYPE type)
{
switch (type)
{
case NIKE:
return new NiKeShoes();
break;
case LINING:
return new LiNingShoes();
break;
case ADIDAS:
return new AdidasShoes();
break;
default:
return NULL;
break;
}
}
};
int main()
{
// 构造工厂对象
ShoesFactory shoesFactory;
// 从鞋工厂对象创建阿迪达斯鞋对象
Shoes *pNikeShoes = shoesFactory.CreateShoes(NIKE);
if (pNikeShoes != NULL)
{
// 耐克球鞋广告喊起
pNikeShoes->Show();
// 释放资源
delete pNikeShoes;
pNikeShoes = NULL;
}
// 从鞋工厂对象创建阿迪达斯鞋对象
Shoes *pLiNingShoes = shoesFactory.CreateShoes(LINING);
if (pLiNingShoes != NULL)
{
// 李宁球鞋广告喊起
pLiNingShoes->Show();
// 释放资源
delete pLiNingShoes;
pLiNingShoes = NULL;
}
// 从鞋工厂对象创建阿迪达斯鞋对象
Shoes *pAdidasShoes = shoesFactory.CreateShoes(ADIDAS);
if (pAdidasShoes != NULL)
{
// 阿迪达斯球鞋广告喊起
pAdidasShoes->Show();
// 释放资源
delete pAdidasShoes;
pAdidasShoes = NULL;
}
return 0;
}
工厂模式
工厂方法是一种创建(Creational)设计模式,它解决了创建产品对象而不指定其具体类的问题。Factory方法定义了一个方法,该方法应该用于创建对象,而不是直接调用构造函数(new操作符)。子类可以重写此方法来更改将要创建的对象的类。
例:
情景:为了生产某种鞋子,需要为不同牌子的鞋开设独立的生产线。
抽象工厂类:提供创建具体产品类的接口
具体工厂类:继承抽象工厂,实现创建具体产品对象
抽象产品类:具体产品类的接口
具体产品类:具体工厂要创建的对象
特点:工厂部分抽象出了接口,实现交给子类
缺点:新增产品时,要增加对应产品的具体工厂类。
// 总鞋厂
class ShoesFactory // Factory interface
{
public:
virtual Shoes *CreateShoes() = 0;
virtual ~ShoesFactory() {}
};
// 耐克生产者/生产链
class NiKeProducer : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new NiKeShoes();
}
};
// 阿迪达斯生产者/生产链
class AdidasProducer : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new AdidasShoes();
}
};
// 李宁生产者/生产链
class LiNingProducer : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new LiNingShoes();
}
};
int main()
{
// ================ 生产耐克流程 ==================== //
// 鞋厂开设耐克生产线
ShoesFactory *niKeProducer = new NiKeProducer();
// 耐克生产线产出球鞋
Shoes *nikeShoes = niKeProducer->CreateShoes();
// 耐克球鞋广告喊起
nikeShoes->Show();
// 释放资源
delete nikeShoes;
delete niKeProducer;
// ================ 生产阿迪达斯流程 ==================== //
// 鞋厂开设阿迪达斯生产者
ShoesFactory *adidasProducer = new AdidasProducer();
// 阿迪达斯生产线产出球鞋
Shoes *adidasShoes = adidasProducer->CreateShoes();
// 阿迪达斯球鞋广喊起
adidasShoes->Show();
// 释放资源
delete adidasShoes;
delete adidasProducer;
return 0;
}
抽象工厂
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
情景:现在工厂不止产鞋子了,衣服裤子一起产了。
结构与工厂模式一样。
// 基类 衣服
class Clothe
{
public:
virtual void Show() = 0;
virtual ~Clothe() {}
};
// 耐克衣服
class NiKeClothe : public Clothe
{
public:
void Show()
{
std::cout << "我是耐克衣服,时尚我最在行!" << std::endl;
}
};
// 基类 鞋子
class Shoes
{
public:
virtual void Show() = 0;
virtual ~Shoes() {}
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,让你酷起来!" << std::endl;
}
};
//Factory为抽象工厂,提供了创建鞋子CreateShoes()和衣服产品CreateClothe()对象的接口。
//NiKeProducer为具体工厂,实现了创建耐克鞋子和耐克衣服的方式。
// 总厂
class Factory
{
public:
virtual Shoes *CreateShoes() = 0;
virtual Clothe *CreateClothe() = 0;
virtual ~Factory() {}
};
// 耐克生产者/生产链
class NiKeProducer : public Factory
{
public:
Shoes *CreateShoes()
{
return new NiKeShoes();
}
Clothe *CreateClothe()
{
return new NiKeClothe();
}
};
int main()
{
// ================ 生产耐克流程 ==================== //
// 鞋厂开设耐克生产线
Factory *niKeProducer = new NiKeProducer();
// 耐克生产线产出球鞋
Shoes *nikeShoes = niKeProducer->CreateShoes();
// 耐克生产线产出衣服
Clothe *nikeClothe = niKeProducer->CreateClothe();
// 耐克球鞋广告喊起
nikeShoes->Show();
// 耐克衣服广告喊起
nikeClothe->Show();
// 释放资源
delete nikeShoes;
delete nikeClothe;
delete niKeProducer;
return 0;
}
小结:
简单工厂模式,违背了开闭原则。
工厂和抽象工厂,增加产品类时需要增加对应的具体工厂类。
Reference:
https://zhuanlan.zhihu.com/p/83535678
https://zhuanlan.zhihu.com/p/83537599