Factory模式的两个最重要的功能:
(1)定义创建对象的接口,封装了对象的创建;
(2)使得具体化类的工作延迟到子类当中;
(一)简单工厂模式
简单工厂模式是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类。
简单工厂模式的结构图:
Factory Pattern是我们的工厂类,它里边有n多条生产线,每条生产线对应不同的类,生产不同的东西。对于用户,用户只通过产品类去选择产品,至于选择哪条生产线,具体怎样实现生产都是由工厂内部实现的。所以简单工厂模式一是要简化类名,二是屏蔽对象生成的细节。
适用场景:适用于规模固定的工厂;
原因:当有新的生产线想要加入到工厂中的时候,就不符合我们设计模式中的开放-封闭原则(可以对类、模块、函数进行扩展,但不能修改)。就必须去修改我们的工厂类。
简单实现:
class Product
{
public:
Product(std::string name) :mname(name){}
virtual void operation() = 0;
protected:
std::string mname;
};
class Product1 : public Product
{
public:
Product1(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product1!" << std::endl;
}
};
class Product2 : public Product
{
public:
Product2(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product2!" << std::endl;
}
};
class Product3 : public Product
{
public:
Product3(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product3!" << std::endl;
}
};
class Factory
{
public:
Product *CreateProduct(int flag)
{
switch (flag)
{
case 1:
return new Product1("Product1");
break;
case 2:
return new Product2("Product1");
break;
//case 3:
// return new Product3("Product3");
// break;
default:
std::cout << " flag is error !" << std::endl;
break;
}
}
};
简单工厂模式的优点:能够根据外界给定的信息,决定究竟应该创建哪个具体的对象,明确区分了各自的职责和权利,有利于整个软件体系结构的优化。
缺点:工厂类集中了所有实例的创建逻辑,容易违反高内聚的责任分配原则。
(二)、工厂模式(也称工厂方法模式)
定义一个创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类。
工厂模式解决了简单工厂模式的问题,首先是符合设计模式的开放封闭原则,实现了可扩展,不修改。
工厂模式的结构图:
简单的来说,工厂模式就是在Factory类中,提供构造子类ConCreateFactoryd的接口,在子类中具体实现每一个处理不同Product的工厂。
工厂模式的具体实现:
class Product
{
public:
Product(std::string name) :mname(name){}
virtual void operation() = 0;
protected:
std::string mname;
};
class Product1 : public Product
{
public:
Product1(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product1!" << std::endl;
}
};
class Product2 : public Product
{
public:
Product2(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product2!" << std::endl;
}
};
class Product3 : public Product
{
public:
Product3(std::string name) :Product(name){}
virtual void operation()
{
std::cout << "this is Product3!" << std::endl;
}
};
class Factory_1:public Factory
{
public:
Factory_1(std::string name) :Factory(name){}
virtual Product* createProduct()
{
return new Product1("Product1");
}
};
class Factory_2:public Factory
{
public:
Factory_2(std::string name) :Factory(name){}
virtual Product* createProduct()
{
return new Product2("Product2");
}
};
class Factory_3 :public Factory
{
public:
Factory_3(std::string name) :Factory(name){}
virtual Product* createProduct()
{
return new Product3("Product3");
}
};
class Factory
{
public:
Factory(std::string name) :mname(name){}
virtual Product* createProduct() = 0;
protected:
std::string mname;
};
工厂模式的优点:
基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现;利用纯虚函数实现;
产品类的实现如何变化,调用者都不需要关心,只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不会变化;
高层模式只需要知道产品的抽象类,其他的实现类都不需要关心;
实现了多态性;
缺点:每增加一种产品,就需要增加一个对象工厂。相比简单工厂模式,工厂方法模式需要定义更多的类。
(三)抽象工厂模式
抽象工厂模式是用来解决:要创建一组相关或者相互依赖的对象。
抽象工厂模式的结构图:
抽象工厂模式关键就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中,维护这样一个创建类总比维护n多相关对象的创建过程要简单的多。
抽象工厂模式的简单实现:
class ProductA
{
public:
ProductA(string myname):name(myname){};
virtual void operation()=0;
private:
string name;
};
class A1:public ProductA
{
public:
A1(string myname):ProductA(myname){};
void operation()
{
cout << "A1" << endl;
}
};
class A2:public ProductA
{
public:
A2(string myname):ProductA(myname){};
void operation()
{
cout << "A2" << endl;
}
};
class ProductB
{
public:
ProductB(string myname):name(myname){};
virtual void operation()=0;
private:
string name;
};
class B1:public ProductB
{
public:
B1(string myname):ProductB(myname){};
void operation()
{
cout << "B1" << endl;
}
};
class B2:public ProductB
{
public:
B2(string myname):ProductB(myname){};
void operation()
{
cout << "B2" << endl;
}
};
class AbstractFactor
{
public:
AbstractFactor(string myname):name(myname){};
virtual ProductA* CreateA() = 0;
virtual ProductB* CreateB() = 0;
private:
string name;
};
class Factory1:public AbstractFactor
{
public:
Factory1(string myname):AbstractFactor(myname){};
ProductA* CreateA()
{
return new A1("A1");
}
ProductB* CreateB()
{
return new B1("B1");
}
};
class Factory2:public AbstractFactor
{
public:
Factory2(string myname):AbstractFactor(myname){};
ProductA* CreateA()
{
return new A2("A2");
}
ProductB* CreateB()
{
return new B2("B2");
}
};
抽象工厂模式是为创建一组(有多类)相关或依赖的对象提供创建接口;而工厂模式是为一类对象提供创建接口或延迟对象到子类中实现。并且可以看到,抽象工厂模式通常都是使用工厂模式实现的。
抽象工厂模式的优点:
- 它分离了具体的类;
- 它使得易于交换产品系列;
- 它有利于产品的一致性;
缺点:难以支持新种类的产品;
总说:
"开放-封闭"原则要求系统对扩展开放,对修改封闭。通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:
增加产品族:Abstract Factory很好的支持了"开放-封闭"原则。
增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持"开放-封闭"原则。
综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。
参考书籍:《c++设计模式》