用一个单独的类来做创造实例的过程,就是工厂。
简单工厂模式
简单工厂模式基本代码
#include <iostream>
using namespace std;
class AbstractProduct {
public:
virtual ~AbstractProduct() {}
virtual void Operation() = 0;
};
class ProductA : public AbstractProduct {
public:
void Operation() { cout << "ProductA" << endl; }
};
class ProductB : public AbstractProduct {
public:
void Operation() { cout << "ProductB" << endl; }
};
class Factory {
public:
AbstractProduct* createProduct(char product) {
AbstractProduct* ap = NULL;
switch(product) {
case 'A': ap = new ProductA(); break;
case 'B': ap = new ProductB(); break;
}
return ap;
}
};
int main() {
Factory* f = new Factory();
AbstractProduct* apa = f->createProduct('A');
apa->Operation(); // ProductA
AbstractProduct* apb = f->createProduct('B');
apb->Operation(); // ProductB
delete apa;
delete apb;
delete f;
return 0;
}
简单运算工厂
class OperationFactory {
public:
Operation createOperate(string operate) {
Operation oper = null;
switch (operate) {
case "+": oper = new OperationAdd(); break;
case "-": oper = new OperationSub(); break;
case "*": oper = new OperationMul(); break;
case "/": oper = new OperationDiv(); break;
}
return oper;
}
};
面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
工厂方法模式
工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。
工厂方法模式结构图
工厂方法模式基本代码
#include <iostream>
using namespace std;
class Product {
public:
virtual ~Product(){}
virtual void Operation() = 0;
};
class ConcreteProductA : public Product {
public:
void Operation() { cout << "ConcreteProductA" << endl; }
};
class ConcreteProductB : public Product {
public:
void Operation() { cout << "ConcreteProductB" << endl; }
};
class Creator{
public:
virtual Product* FactoryMethod() = 0;
virtual ~Creator(){}
};
class ConcreteCreatorA : public Creator {
public:
Product* FactoryMethod() { return new ConcreteProductA(); }
};
class ConcreteCreatorB : public Creator {
public:
Product* FactoryMethod() { return new ConcreteProductB(); }
};
int main() {
Creator* ca = new ConcreteCreatorA();
Product* pa = ca->FactoryMethod();
pa->Operation(); // ConcreteProductA
Creator* cb = new ConcreteCreatorB();
Product* pb = cb->FactoryMethod();
pb->Operation(); // ConcreteProductB
delete ca;
delete pa;
delete cb;
delete pb;
return 0;
}
把简单工厂模式中的工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,就变成了一个工厂抽象接口和多个具体生成对象的工厂。
这样整个工厂和产品体系就没有修改,而只是扩展,符合开放-封闭原则。
抽象工厂模式
抽象工厂模式是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式结构图
抽象工厂模式基本代码
#include <iostream>
using namespace std;
class AbstractProductA {
public:
virtual ~AbstractProductA(){}
virtual void Operation() = 0;
};
class ProductA1 : public AbstractProductA {
public:
void Operation() {
cout << "ProductA1" << endl;
}
};
class ProductA2 : public AbstractProductA {
public:
void Operation() {
cout << "ProductA2" << endl;
}
};
class AbstractProductB {
public:
virtual ~AbstractProductB(){}
virtual void Operation() = 0;
};
class ProductB1 : public AbstractProductB {
public:
void Operation() {
cout << "ProductB1" << endl;
}
};
class ProductB2 : public AbstractProductB {
public:
void Operation() {
cout << "ProductB2" << endl;
}
};
class AbstractFactory {
public:
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
virtual ~AbstractFactory(){}
};
class ConcreteFactory1 : public AbstractFactory {
public:
ProductA1* CreateProductA() {
return new ProductA1();
}
ProductB1* CreateProductB() {
return new ProductB1();
}
};
class ConcreteFactory2 : public AbstractFactory {
public:
ProductA2* CreateProductA() {
return new ProductA2();
}
ProductB2* CreateProductB() {
return new ProductB2();
}
};
int main() {
AbstractFactory* af1 = new ConcreteFactory1();
// 具体工厂创建对应的具体产品
AbstractProductA* apa1 = af1->CreateProductA(); // 工厂1创建产品A
apa1->Operation(); // ProductA1
AbstractProductB* apb1 = af1->CreateProductB(); // 工厂1创建产品B
apb1->Operation(); // ProductB1
AbstractFactory* af2 = new ConcreteFactory2();
AbstractProductA* apa2 = af2->CreateProductA(); // 工厂2创建产品A
apa2->Operation(); // ProductA2
AbstractProductB* apb2 = af2->CreateProductB(); // 工厂2创建产品B
apb2->Operation(); // ProductB2
delete apa1;
delete apa2;
delete af1;
delete apb1;
delete apb2;
delete af2;
return 0;
}
抽象工厂函数的优缺点
优点:
- 易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这样就使得改变一个应用的具体工厂变得非常容易,只需要改变具体工厂即可使用不同的产品配置。
- 让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离,不会出现在客户代码中。
缺点:增加新的产品时需要改动多处代码。