工厂模式
创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向这个创建的对象。
1、简单工厂模式——所有的“产品”由一个工厂加工完成
设计产品抽象类
class Product
{
public:
Product(std::string name):mname(name){};
virtual void operation() = 0;
virtual ~Product(){}
protected:
std::string mname;
};
有两种产品A、B
class ProductA:public Product
{
public:
ProductA(std::string name):Product(name){};
virtual void operation()//子类实现纯虚函数
{
std::cout<<"this is ProductA"<<std::endl;
}
};
class ProductB:public Product
{
public:
ProductB(std::string name):Product(name){};
virtual void operation()
{
std::cout<<"this is ProductB"<<std::endl;
}
};
一般,简单工厂方法模式中,工厂类中有一个方法,通过switch中不同的值或者if else语句来创建不同的对象并返回。
class Factory
{
public:
Product* creatProduct(int flag)
{
switch (flag)
{
case 1:
return new ProductA("A");
break;
case 2:
return new ProductB("B");
break;
default:
break;
}
return NULL;
}
};
int main()
{
Factory f;
Product* pp = f.createProduct(1);
pp->operation();//动多态
delete pp;
return 0;
}
2、工厂方法模式——一个“产品”由一个工厂生产
使用简单工厂模式后,如果在上面基础之上想要再添加生产一个C产品,首先要新增C,并且,还要在switch里边,新增一个case分支,来判断是否生产C,所以并不是很合理,所以简单工厂模式违背了开闭原则,扩展性差。
通过工厂方法模式,我们就能解决这一问题。仔细研究,之所以会产生上面的问题,是因为我们只有一个“工厂”,无论那种产品生产,都交给这个工厂去处理导致的。那么,现在,我们可以,设计多个“工厂”,每种工厂只负责生产一种产品。
class Product
{
public:
Product(std::string name) :mname(name){}
virtual void operation() = 0;
virtual ~Product(){}
protected:
std::string mname;
};
class ProductA :public Product
{
public:
ProductA(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class ProductB :public Product
{
public:
ProductB(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class ProductC :public Product
{
public:
ProductC(std::string name) :Product(name){}
void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class Factory
{
public:
virtual Product* createProduct() = 0;
virtual ~Factory(){}
};
class FactoryA :public Factory
{
public:
Product* createProduct()
{
return new ProductA("A");
}
};
class FactoryB :public Factory
{
public:
Product* createProduct()
{
return new ProductB("B");
}
};
class FactoryC :public Factory
{
public:
Product* createProduct()
{
return new ProductC("C");
}
};
int main()
{
Factory* pf = new FactoryC();
Product* pp = pf->createProduct();
pp->operation();
delete pf;
delete pp;
return 0;
}
可以看到,每个工厂只生产一种产品,客户端通过不同的工厂去生产不同的产品,而生产那一产品的逻辑交给客户端这边去处理了。
3、抽象工厂方法
class ProductA
{
public:
ProductA(std::string name) :mname(name){}
virtual void operation() = 0;
virtual ~ProductA(){}
protected:
std::string mname;
};
class ProductA1 :public ProductA
{
public:
ProductA1(std::string name) :ProductA(name){}
void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class ProductA2 :public ProductA
{
public:
ProductA2(std::string name) :ProductA(name){}
void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class ProductB
{
public:
ProductB(std::string name) :mname(name){}
virtual void operation() = 0;
virtual ~ProductB(){}
protected:
std::string mname;
};
class ProductB1 :public ProductB
{
public:
ProductB1(std::string name) :ProductB(name){}
void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class ProductB2 :public ProductB
{
public:
ProductB2(std::string name) :ProductB(name){}
void operation()
{
std::cout << "this is a " << mname << std::endl;
}
};
class AbstractFactory
{
public:
virtual ProductA* createProductA() = 0;
virtual ProductB* createProductB() = 0;
virtual ~AbstractFactory(){}
};
class Factory_1 :public AbstractFactory
{
public:
ProductA* createProductA()
{
return new ProductA1("A1");
}
ProductB* createProductB()
{
return new ProductB1("B1");
}
};
class Factory_2 :public AbstractFactory
{
public:
ProductA* createProductA()
{
return new ProductA2("A2");
}
ProductB* createProductB()
{
return new ProductB2("B2");
}
};
int main()
{
AbstractFactory* paf = new Factory_2();
ProductA* pa = paf->createProductA();
ProductB* pb = paf->createProductB();
pa->operation();
pb->operation();
delete paf;
delete pa;
delete pb;
return 0;
}
可以看到,之所以叫抽象工厂,是因为和工厂方法相比,这里有多个抽象产品类存在(即A1,A2),每个抽象产品类可以派生出多个具体的产品,生产的是系列产品,其工厂接口相对于工厂方法模式而言,是有多个方法的,用来生产不同的抽象产品。
4、总结
- 简单工厂模式:工厂类是整个模式的关键所在,包括必要的逻辑判断,决定究竟创建哪个类的对象。
适用于工厂类需要创建的对象比较少的情况,客户只需要传入具体的参数,就可以忽略工厂的生产细节,去获取想要的对象。 - 工厂方法模式:是对简单工厂方法模式的一个抽象,抽离出了一个Factory类(或者接口),这个接口不负责具体产品的生产,而只是指定一些规范,具体的生产工作由其子类去完成。这个模式中,工厂类和产品类往往是一一对应的,完全解决了简单工厂模式中违背“开闭原则”的问题,实现了可扩展性。
主要是针对单一产品结构的情景。 - 抽象工厂方法:的特点是存在多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,工厂提供多种方法,去生产“系列”产品。
每种模式都有自己的优点和弊端,没有最好的模式,只有最适合的模式,只要符合实际开发需求就是最好的。