在面向对象的系统设计中经常会遇到以下两类问题:
(1)为了实现高内聚和低耦合,我们经常会抽象出一些类的公共接口以形成抽象基类或者接口,这样我们可以通过声明一个基类的指针指向实际的子类来实现,达到了多态的目的。这里很容易出现的一个问题n多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如new XXX的代码,这里带来两个问题:1>客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同程序员千奇百怪的个人偏好了;2>程序的扩展性和维护变得越来越困难。
(2)还有一种情况就是在父类中并不知道具体要实例化哪一个具体的子类。这里的意思为:假设我们在类A中要使用到类B, B是一个抽象父类,在A中并不知道具体要实例化那一个B的子类,但是在类A的子类D中是可以知道的,在A中我们没有办法直接使用类
似于new XXX的语句,因为根本就不知道XXX是什么。
以上两个问题也就引出了Factory模式的两个最重要的功能:
1>定义创建对象的接口;
2>封装了对象的创建。
工厂模式有三种:简单工厂模式、工厂方法模式和抽象工厂模式。
(1)简单工厂模式
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一类产品类(这些产品类继承自一个父类或接口)的实例。假设有一个工厂,它能生产出ProductA、ProductB两种产品,当客户需要产品的时候一定要告诉工厂需要哪种产品,是ProductA还是ProductB,这个工厂根据传入的参数,动态决定应该创建哪一类产品类的实例。但是当增加一种新产品的时候,就要去修改工厂类(在工厂类中添加case语句),这样就违背了设计原则中的开放封闭原则,所谓开放封闭原则就是对扩展开放对修改封闭,新版本的设计代码可以沿用旧版本的代码,但不能修改旧的代码。
#include <iostream>
using namespace std;
//简单工厂模式
class Product
{
protected:
string productname;
public:
Product(string name):productname(name)
{}
virtual void operation()=0;//纯虚函数,提供一个生产产品的接口,具体在子类中实现
};
class ProductA:public Product
{
public:
ProductA(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductA"<<endl;
}
};
class ProductB:public Product
{
public:
ProductB(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductB"<<endl;
}
};
class Factory
{
public:
Product* CreateProduct(int flag)
{
switch(flag)
{
case 1:
return new ProductA("ProductA");
break;
case 2:
return new ProductB("ProductB");
break;
default:
cout<<"flag is error!"<<endl;
break;
}
}
};
int main()
{
Factory fac;
Product* p1=fac.CreateProduct(1);
p1->operation();
p1=fac.CreateProduct(2);
p1->operation();
}
运行结果如下:
当增加一种新产品ProductC时,需要修改工厂类,在工厂类中添加case语句生成ProductC这个对象,再增加一个Product的派生类去实现这个对象,修改后的代码如下:
#include <iostream>
using namespace std;
//简单工厂模式,增加一个新产品ProductC
class Product
{
protected:
string productname;
public:
Product(string name):productname(name)
{}
virtual void operation()=0;
};
class ProductA:public Product
{
public:
ProductA(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductA"<<endl;
}
};
class ProductB:public Product
{
public:
ProductB(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductB"<<endl;
}
};
class ProductC:public Product
{
public:
ProductC(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductC"<<endl;
}
};
class Factory
{
public:
Product* CreateProduct(int flag)
{
switch(flag)
{
case 1:
return new ProductA("ProductA");
break;
case 2:
return new ProductB("ProductB");
break;
case 3:
return new ProductC("ProductC");
break;
default:
cout<<"flag is error!"<<endl;
break;
}
}
};
int main()
{
Factory fac;
Product* p1=fac.CreateProduct(1);
p1->operation();
p1=fac.CreateProduct(2);
p1->operation();
p1=fac.CreateProduct(3);
p1->operation();
}
运行结果如下:
(2)工厂方法模式
工厂方法模式解决了简单工厂模式增加一种新产品时,要去修改工厂类的缺点,所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。假如一个工厂有两个子工厂Factory_1和Factory_2,子工厂Factory_1负责生产ProductA,子工厂Factory_2负责生产ProductB,这时候客户就不需要告诉工厂生产哪种产品了,只需要告诉工厂生产就可以了。当增加一种新产品时, 使用工厂方法模式不用修改原来旧版本的的代码,只需另外增加一个工厂Factory的派生类就行,新增加的这个派生类去生产新产品,这样就不会违背开放封闭设计原则,这样的设计也符合五大设计原则中的依赖倒置原则,“抽象不应依赖于细节,细节应该依赖于抽象”,先抽象后具体,从笼统到细节,先生产出抽象程度比较高的实体(产品各自对应的工厂),然后在生产更加细节化的实体(产品)。
#include <iostream>
using namespace std;
//工厂方法模式
class Product
{
protected:
string productname;
public:
Product(string name):productname(name)
{}
virtual void operation()=0;
};
class ProductA:public Product
{
public:
ProductA(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductA"<<endl;
}
};
class ProductB:public Product
{
public:
ProductB(string name):Product(name)
{}
virtual void operation()
{
cout<<"This is ProductB"<<endl;
}
};
class Factory
{
protected:
string factoryname;
public:
Factory(string name):factoryname(name)
{}
virtual Product* CreateProduct()=0;
};
class Factory_1:public Factory
{
public:
Factory_1(string name):Factory(name)
{}
virtual Product* CreateProduct()
{
return new ProductA("ProductA");
}
};
class Factory_2:public Factory
{
public:
Factory_2(string name):Factory(name)
{}
virtual Product* CreateProduct()
{
return new ProductB("ProductB");
}
};
int main()
{
Factory* fac1=new Factory_1("f1");
Product* p1=fac1->CreateProduct();
p1->operation();
Factory* fac2=new Factory_2("f2");
Product* p2=fac2->CreateProduct();
p2->operation();
}
运行结果如下:
(3)抽象工厂模式
上面的两种模式生产的产品都有都有的基类,如果要生产的产品是组合型的,组合型的产品没有共同的基类,这就需要有抽象工厂模式,抽象工厂模式为不同类的类提供一个创建对象的接口。假如ProductA有ProductA1和ProductA2两种形式,ProductB有ProductB1和ProductB2两种形式,而现在需要的这个产品由ProductA1和ProductB1组成,或者由ProductA2和ProductB2组成,这就需要用抽象工厂模式,在抽象工厂类中定义CreateProductA和CreateProductB这两个接口,在子类中生成产品需要的两个对象,对象调用方法就可产生对应的产品。
#include <iostream>
using namespace std;
//抽象工厂模式
class AbstractProductA
{
protected:
string productname;
public:
AbstractProductA(string name):productname(name)
{}
virtual void operation()=0;
};
class ProductA1:public AbstractProductA
{
public:
ProductA1(string name):AbstractProductA(name)
{}
virtual void operation()
{
cout<<"This is ProductA1"<<endl;
}
};
class ProductA2:public AbstractProductA
{
public:
ProductA2(string name):AbstractProductA(name)
{}
virtual void operation()
{
cout<<"This is ProductA2"<<endl;
}
};
class AbstractProductB
{
protected:
string productname;
public:
AbstractProductB(string name):productname(name)
{}
virtual void operation()=0;
};
class ProductB1:public AbstractProductB
{
public:
ProductB1(string name):AbstractProductB(name)
{}
virtual void operation()
{
cout<<"This is ProductB1"<<endl;
}
};
class ProductB2:public AbstractProductB
{
public:
ProductB2(string name):AbstractProductB(name)
{}
virtual void operation()
{
cout<<"This is ProductB2"<<endl;
}
};
class AbstractFactory
{
private:
string factoryname;
public:
AbstractFactory(string name):factoryname(name)
{}
virtual AbstractProductA *CreateProductA()=0;
virtual AbstractProductB *CreateProductB()=0;
};
class Factory_1:public AbstractFactory
{
public:
Factory_1(string name):AbstractFactory(name)
{}
virtual AbstractProductA *CreateProductA()
{
return new ProductA1("ProductA1");
}
virtual AbstractProductB *CreateProductB()
{
return new ProductB1("ProductB1");
}
};
class Factory_2:public AbstractFactory
{
public:
Factory_2(string name):AbstractFactory(name)
{}
virtual AbstractProductA *CreateProductA()
{
return new ProductA2("ProductA2");
}
virtual AbstractProductB *CreateProductB()
{
return new ProductB2("ProductB2");
}
};
int main()
{
AbstractFactory *fac1=new Factory_1("f1");
AbstractProductA *pa1=fac1->CreateProductA();
AbstractProductB *pb1=fac1->CreateProductB();
pa1->operation();
pb1->operation();
AbstractFactory *fac2=new Factory_2("f2");
AbstractProductA *pa2=fac2->CreateProductA();
AbstractProductB *pb2=fac2->CreateProductB();
pa2->operation();
pb2->operation();
return 0;
}
运行结果如下: