工厂模式属于创建型模式,可分为三类,简单工厂模式、工厂方法模式、抽象工厂模式;这三类模式是由易到难,由简到繁的。下面简单阐述一下这三种工厂模式
简单工厂模式
简介说明
简单工厂模式是工厂模式中最简单的一类;它是一个工厂生产多种不同的产品;对外隐藏类产品的实现细节,只暴露需要的产品类型。客户提供需要产品的产品类型给到工厂,就会返回相应的产品。客户只需要关心产品的基类类,不需要知道获取到的是哪一个子类。
使用场景: 常用于多种同类型类的情况,可以将这些类进行隐藏、提供同一接口,这样有利于维护和修改。
优点: 1.隐藏了对象创建的细节,将产品的实例化放在子类中实现;2.客户不需要关心使用的是哪类产品,只需要知道哪个工厂就可以了,只需要提供需要的产品的产品类型;3.便于扩展新的产品;4.遵循依赖倒置原则。
缺点: 1.违背开闭原则,每新增一个产品,需要对工厂进行扩展;2,所有产品只能通过一种方式生产,若某一产品需要多种方式或不同方式实例化时,则不适用。
code
enum Production_en {
Production_0 = 0,
Production_1,
Production_2
}; // Production_en
class Production {
public:
virtual void product_fun() = 0;
}; // production
class Pro_0 : public Production {
public:
void product_fun();
}; // Pro_0
class Pro_1 : public Production {
public:
void product_fun();
}; // Pro_1
class Pro_2 : public Production {
public:
void product_fun() override;
}; // Pro_2
class SampleFactory {
public:
Production *create_fun(Production_en pro_type);
}; // sample_factory
void Pro_0::product_fun() {
std::cout << "Pro_0 production" << std::endl;
}
void Pro_1::product_fun() {
std::cout << "Pro_1 production" << std::endl;
}
void Pro_2::product_fun() {
std::cout << "Pro_2 production" << std::endl;
}
Production *SampleFactory::create_fun(Production_en pro_type) {
std::shared_ptr<Production> pro = nullptr;
switch (pro_type) {
case Production_en::Production_0:
pro = std::make_shared<Pro_0>();
break;
case Production_en::Production_1:
pro = std::make_shared<Pro_1>();
break;
case Production_en::Production_2:
pro = std::make_shared<Pro_2>();
break;
default:
std::cout << "Don't support this type " << pro_type << std::endl;
return nullptr;
}
return pro.get();
}
int main(){
std::shared_ptr<SampleFactory> factory = std::make_shared<SampleFactory>();
factory->create_fun(Production_en::Production_0)->product_fun();
factory->create_fun(Production_en::Production_1)->product_fun();
factory->create_fun(Production_en::Production_2)->product_fun();
return 0;
}
工厂方法模式
简介说明
工厂方法模式:是指一个工厂只生产一类产品;若需要添加新产品,只需要添加一个相应的工厂即可,这样就遵守了开闭原则。
使用场景: 和简单工厂模式相一致,只不过工厂方法模式遵守了开闭原则,使其更具有弹性。将实例化推迟到子类中实现,由子类决定实例化对象。
**优点:**相对于简单工厂模式,多了一个遵守开闭原则,使其更具有弹性。
**缺点:**每增加一种产品,就需要增加一个工厂。若产品过多,则工厂也会有相应的数量。
code
class ProBasic {
public:
virtual void product_fun() = 0;
}; // ProBasic
class Pro_0 : public ProBasic {
public:
void product_fun() override;
}; //Pro_0
class Pro_1 : public ProBasic {
public:
void product_fun() override;
}; //Pro_1
class Pro_2 : public ProBasic {
public:
void product_fun() override;
}; //Pro_2
class FactoryBasic {
public:
virtual std::shared_ptr<ProBasic> create() = 0;
}; // FactoryBasic
class Factory_0 : public FactoryBasic {
public:
std::shared_ptr<ProBasic> create() override;
}; // Factory_0
class Factory_1 : public FactoryBasic {
public:
std::shared_ptr<ProBasic> create() override;
}; // Factory_1
class Factory_2 : public FactoryBasic {
public:
std::shared_ptr<ProBasic> create() override;
}; // Factory_2
void Pro_0::product_fun() {
std::cout << "Pro_0" << std::endl;
}
void Pro_1::product_fun() {
std::cout << "Pro_1" << std::endl;
}
void Pro_2::product_fun() {
std::cout << "Pro_2" << std::endl;
}
std::shared_ptr<ProBasic> Factory_0::create() {
std::cout << "Factory_0 product Pro_0" << std::endl;
return std::make_shared<Pro_0>();
}
std::shared_ptr<ProBasic> Factory_1::create() {
std::cout << "Factory_1 product Pro_1" << std::endl;
return std::make_shared<Pro_1>();
}
std::shared_ptr<ProBasic> Factory_2::create() {
std::cout << "Factory_2 product Pro_2" << std::endl;
return std::make_shared<Pro_2>();
}
int main(){
std::shared_ptr<Factory_0> factory_0 = std::make_shared<Factory_0>();
factory_0->create();
std::shared_ptr<Factory_1> factory_1 = std::make_shared<Factory_1>();
factory_1->create();
std::shared_ptr<Factory_2> factory_3 = std::make_shared<Factory_2>();
factory_1->create();
return 0;
}
抽象工厂模式
简介说明
相比于前两种工厂模式,抽象工厂模式比较复杂;犹如上面提到的简单工厂和工厂方法,需要产品子类必须是同一类型,拥有共同的方法,这样将会限制产品种类的扩展;于是为提高扩展性,抽象工厂将同一类的产品归为一类(即为一组产品);然后将不同组的产品组合为族。此时,客户使用时不需要知道哪一个工厂生产哪一族产品。每一个子类工厂只生产一族产品。通过指定子类工厂生产指定子类产品。
优点: 1.封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。2.可以支持不同类型的产品,使得模式灵活性更强。3.可以非常方便的使用一族中间的不同类型的产品。
缺点: 1.结构太过臃肿,如果产品类型比较多,或者产品族类比较多,不利于扩展和维护。2.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
code
class ProductionBasicA{
public:
virtual void create_a() = 0;
};
class ProductionA_1 : public ProductionBasicA{
public:
void create_a() override;
};
class ProductionA_2 : public ProductionBasicA{
public:
void create_a() override;
};
class ProductionBasicB{
public:
virtual void create_b() = 0;
};
class ProductionB_1 : public ProductionBasicB{
public:
void create_b() override;
};
class ProductionB_2 : public ProductionBasicB{
public:
void create_b() override;
};
class FactoryBasic{
public:
virtual std::shared_ptr<ProductionBasicA> create_production_a() = 0;
virtual std::shared_ptr<ProductionBasicB> create_production_b() = 0;
};
class Factory1: public FactoryBasic{
public:
std::shared_ptr<ProductionBasicA> create_production_a() override;
std::shared_ptr<ProductionBasicB> create_production_b() override;
};
class Factory2: public FactoryBasic{
public:
std::shared_ptr<ProductionBasicA> create_production_a() override;
std::shared_ptr<ProductionBasicB> create_production_b() override;
};
void ProductionA_1::create_a() {
std::cout << "ProductionA_1" << std::endl;
}
void ProductionA_2::create_a() {
std::cout << "ProductionA_2" << std::endl;
}
void ProductionB_1::create_b() {
std::cout << "ProductionB_1" << std::endl;
}
void ProductionB_2::create_b() {
std::cout << "ProductionB_2" << std::endl;
}
std::shared_ptr<ProductionBasicA> Factory1::create_production_a() {
std::cout << "Factory1 product ProductionA_1" << std::endl;
return std::make_shared<ProductionA_1>();
}
std::shared_ptr<ProductionBasicB> Factory1::create_production_b() {
std::cout << "Factory1 product ProductionB_1" << std::endl;
return std::make_shared<ProductionB_1>();
}
std::shared_ptr<ProductionBasicA> Factory2::create_production_a() {
std::cout << "Factory2 product ProductionA_2" << std::endl;
return std::make_shared<ProductionA_2>();
}
std::shared_ptr<ProductionBasicB> Factory2::create_production_b() {
std::cout << "Factory2 product ProductionB_2" << std::endl;
return std::make_shared<ProductionB_2>();
}
int main(){
std::shared_ptr<Factory1> factory_1 = std::make_shared<Factory1>();
factory_1->create_production_a();
factory_1->create_production_b();
std::shared_ptr<Factory2> factory_2 = std::make_shared<Factory2>();
factory_2->create_production_a();
factory_2->create_production_b();
return 0;
}